├── example ├── .watchmanconfig ├── jest.config.js ├── app.json ├── .bundle │ └── config ├── babel.config.js ├── .eslintrc.js ├── android │ ├── app │ │ ├── src │ │ │ ├── main │ │ │ │ ├── res │ │ │ │ │ ├── values │ │ │ │ │ │ ├── strings.xml │ │ │ │ │ │ └── styles.xml │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ └── drawable │ │ │ │ │ │ └── rn_edit_text_material.xml │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java │ │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ └── MainApplication.java │ │ │ ├── debug │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── java │ │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ └── ReactNativeFlipper.java │ │ │ └── release │ │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── ReactNativeFlipper.java │ │ ├── debug.keystore │ │ ├── proguard-rules.pro │ │ └── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── settings.gradle │ ├── build.gradle │ ├── gradle.properties │ ├── gradlew.bat │ └── gradlew ├── ios │ ├── example │ │ ├── Images.xcassets │ │ │ ├── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ ├── AppDelegate.h │ │ ├── main.m │ │ ├── AppDelegate.mm │ │ ├── Info.plist │ │ └── LaunchScreen.storyboard │ ├── example.xcworkspace │ │ ├── xcshareddata │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ └── IDEWorkspaceChecks.plist │ │ └── contents.xcworkspacedata │ ├── .xcode.env │ ├── exampleTests │ │ ├── Info.plist │ │ └── ExampleTests.m │ ├── Podfile │ ├── example.xcodeproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Example.xcscheme │ └── Podfile.lock ├── .prettierrc.js ├── index.js ├── Gemfile ├── App │ ├── styles │ │ └── AppStyles.tsx │ ├── RippleEffectButton.tsx │ ├── PulseSpinnerButton.tsx │ ├── MaterialSpinnerButton.tsx │ ├── UIActivitySpinnerButton.tsx │ ├── WaveSpinnerButton.tsx │ ├── BarSpinnerButton.tsx │ ├── App.tsx │ ├── DefaultOrBallSpinnerButton.tsx │ ├── PacmanSpinnerButton.tsx │ ├── SkypeSpinnerButton.tsx │ └── DotSpinnerButton.tsx ├── tsconfig.json ├── .gitignore ├── metro.config.js ├── package.json ├── Gemfile.lock └── README.md ├── .eslintignore ├── .husky ├── pre-push ├── pre-commit └── commit-msg ├── src ├── styles │ ├── index.ts │ └── SpinnerButtonStyle.ts ├── index.ts ├── components │ ├── AnimatedView │ │ ├── index.ts │ │ ├── AnimatedTypes.ts │ │ └── AnimatedView.tsx │ ├── AnimatableView │ │ ├── index.ts │ │ ├── AnimatableTypes.ts │ │ └── AnimatableView.tsx │ ├── ChildrenView │ │ ├── index.ts │ │ ├── ChildrenViewTypes.ts │ │ └── ChildrenView.tsx │ ├── SpinnerButton │ │ ├── index.ts │ │ ├── SpinnerButton.tsx │ │ └── SpinnerButtonTypes.ts │ ├── LinearGradient │ │ ├── index.ts │ │ ├── LinearGradientTypes.ts │ │ └── LinearGradient.tsx │ ├── RadialGradient │ │ ├── index.ts │ │ ├── RadialGradientTypes.ts │ │ └── RadialGradient.tsx │ ├── SpinnerComponent │ │ ├── index.ts │ │ ├── SpinnerComponentTypes.ts │ │ └── SpinnerComponent.tsx │ └── index.ts └── utils │ ├── getPercentageFromAngle.tsx │ ├── index.tsx │ ├── SpinnerUtils.tsx │ ├── useRippleButton.ts │ ├── getAnglePercentageObject.tsx │ ├── useAnimatedValues.tsx │ └── GradientData.json ├── assets ├── example.gif ├── exampleDemo1.gif ├── exampleDemo2.gif └── react-native-spinner-button.png ├── jest.config.js ├── .npmignore ├── .prettierrc.js ├── .github └── workflows │ └── publish.yml ├── .eslintrc ├── CONTRIBUTING.md ├── tsconfig.json ├── LICENSE ├── .gitignore ├── package.json └── README.md /example/.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | **/node_modules 2 | example/ 3 | lib/ 4 | node_modules/ -------------------------------------------------------------------------------- /.husky/pre-push: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | yarn build -------------------------------------------------------------------------------- /example/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'react-native', 3 | }; 4 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | yarn lint-staged -------------------------------------------------------------------------------- /example/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "displayName": "example" 4 | } 5 | -------------------------------------------------------------------------------- /example/.bundle/config: -------------------------------------------------------------------------------- 1 | BUNDLE_PATH: "vendor/bundle" 2 | BUNDLE_FORCE_RUBY_PLATFORM: 1 3 | -------------------------------------------------------------------------------- /src/styles/index.ts: -------------------------------------------------------------------------------- 1 | export { default as SpinnerButtonStyle } from './SpinnerButtonStyle'; 2 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | yarn commitlint --edit $1 -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { SpinnerButton } from './components'; 2 | export { SpinnerButton as default }; 3 | -------------------------------------------------------------------------------- /example/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:metro-react-native-babel-preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /assets/example.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimformSolutionsPvtLtd/react-native-spinner-button/HEAD/assets/example.gif -------------------------------------------------------------------------------- /assets/exampleDemo1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimformSolutionsPvtLtd/react-native-spinner-button/HEAD/assets/exampleDemo1.gif -------------------------------------------------------------------------------- /assets/exampleDemo2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimformSolutionsPvtLtd/react-native-spinner-button/HEAD/assets/exampleDemo2.gif -------------------------------------------------------------------------------- /example/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: '@react-native', 4 | requireConfigFile: false 5 | }; 6 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | example 3 | 4 | -------------------------------------------------------------------------------- /example/ios/example/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/components/AnimatedView/index.ts: -------------------------------------------------------------------------------- 1 | export { default as AnimatedView } from './AnimatedView'; 2 | export * from './AnimatedTypes'; 3 | -------------------------------------------------------------------------------- /src/components/AnimatableView/index.ts: -------------------------------------------------------------------------------- 1 | export { default as AnimatableView } from './AnimatableView'; 2 | export * from './AnimatableTypes'; 3 | -------------------------------------------------------------------------------- /src/components/ChildrenView/index.ts: -------------------------------------------------------------------------------- 1 | export { default as ChildrenView } from './ChildrenView'; 2 | export * from './ChildrenViewTypes'; 3 | -------------------------------------------------------------------------------- /src/components/SpinnerButton/index.ts: -------------------------------------------------------------------------------- 1 | export { default as SpinnerButton } from './SpinnerButton'; 2 | export * from './SpinnerButtonTypes'; 3 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: "react-native", 3 | moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"], 4 | }; -------------------------------------------------------------------------------- /src/components/LinearGradient/index.ts: -------------------------------------------------------------------------------- 1 | export { default as LinearGradient } from './LinearGradient'; 2 | export * from './LinearGradientTypes'; 3 | -------------------------------------------------------------------------------- /src/components/RadialGradient/index.ts: -------------------------------------------------------------------------------- 1 | export { default as RadialGradient } from './RadialGradient'; 2 | export * from './RadialGradientTypes'; 3 | -------------------------------------------------------------------------------- /example/android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimformSolutionsPvtLtd/react-native-spinner-button/HEAD/example/android/app/debug.keystore -------------------------------------------------------------------------------- /example/ios/example/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : RCTAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /src/components/SpinnerComponent/index.ts: -------------------------------------------------------------------------------- 1 | export { default as SpinnerComponent } from './SpinnerComponent'; 2 | export * from './SpinnerComponentTypes'; 3 | -------------------------------------------------------------------------------- /assets/react-native-spinner-button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimformSolutionsPvtLtd/react-native-spinner-button/HEAD/assets/react-native-spinner-button.png -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .github/ 2 | example/ 3 | assets/ 4 | .eslintignore 5 | .eslintrc 6 | CONTRIBUTING.md 7 | babel.config.js 8 | .buckconfig 9 | jest-setup.js 10 | .husky/ -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | arrowParens: 'avoid', 3 | bracketSameLine: true, 4 | bracketSpacing: true, 5 | singleQuote: true, 6 | trailingComma: 'es5' 7 | }; -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimformSolutionsPvtLtd/react-native-spinner-button/HEAD/example/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /example/.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | arrowParens: 'avoid', 3 | bracketSameLine: true, 4 | bracketSpacing: false, 5 | singleQuote: true, 6 | trailingComma: 'all', 7 | }; 8 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimformSolutionsPvtLtd/react-native-spinner-button/HEAD/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimformSolutionsPvtLtd/react-native-spinner-button/HEAD/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimformSolutionsPvtLtd/react-native-spinner-button/HEAD/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimformSolutionsPvtLtd/react-native-spinner-button/HEAD/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimformSolutionsPvtLtd/react-native-spinner-button/HEAD/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimformSolutionsPvtLtd/react-native-spinner-button/HEAD/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimformSolutionsPvtLtd/react-native-spinner-button/HEAD/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimformSolutionsPvtLtd/react-native-spinner-button/HEAD/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimformSolutionsPvtLtd/react-native-spinner-button/HEAD/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SimformSolutionsPvtLtd/react-native-spinner-button/HEAD/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | import { AppRegistry } from 'react-native'; 5 | import App from './App/App' 6 | import {name as appName} from './app.json'; 7 | 8 | AppRegistry.registerComponent(appName, () => App); -------------------------------------------------------------------------------- /example/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version 4 | ruby ">= 2.6.10" 5 | 6 | gem 'cocoapods', '~> 1.13' 7 | gem 'activesupport', '>= 6.1.7.3', '< 7.1.0' 8 | -------------------------------------------------------------------------------- /example/ios/example.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /example/ios/example/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | @autoreleasepool { 8 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/components/index.ts: -------------------------------------------------------------------------------- 1 | export * from './AnimatableView'; 2 | export * from './AnimatedView'; 3 | export * from './ChildrenView'; 4 | export * from './LinearGradient'; 5 | export * from './RadialGradient'; 6 | export * from './SpinnerButton'; 7 | export * from './SpinnerComponent'; 8 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'example' 2 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) 3 | include ':app' 4 | includeBuild('../node_modules/@react-native/gradle-plugin') 5 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.1-all.zip 4 | networkTimeout=10000 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /example/ios/example.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/example.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/components/AnimatedView/AnimatedTypes.ts: -------------------------------------------------------------------------------- 1 | import type { ViewStyle, Animated } from 'react-native'; 2 | import type { CommonViewProps } from '..'; 3 | 4 | export type AnimatedStyle = Animated.WithAnimatedValue; 5 | 6 | export type AnimatedViewProps = CommonViewProps & { 7 | animatedChildHideStyle?: AnimatedStyle; 8 | animatedChildShowStyle?: AnimatedStyle; 9 | }; 10 | -------------------------------------------------------------------------------- /src/utils/getPercentageFromAngle.tsx: -------------------------------------------------------------------------------- 1 | const step: number = 100 / 90; 2 | 3 | const getPercentageFromAngle = ( 4 | angle: number, 5 | minVal: number, 6 | isRev = false 7 | ): number => { 8 | const actualDeg: number = angle - minVal; 9 | const percentage: number = step * actualDeg; 10 | return isRev ? 100 - percentage : percentage; 11 | }; 12 | 13 | export default getPercentageFromAngle; 14 | -------------------------------------------------------------------------------- /src/components/SpinnerComponent/SpinnerComponentTypes.ts: -------------------------------------------------------------------------------- 1 | import type { ColorValue } from 'react-native'; 2 | import type { SpinnerType } from '..'; 3 | import type { SpinnerOptionsProp } from '..'; 4 | 5 | export type SpinnerComponentProp = { 6 | height: number; 7 | spinnerColor: ColorValue; 8 | spinnerType: SpinnerType; 9 | indicatorCount?: number; 10 | size: number; 11 | spinnerOptions?: SpinnerOptionsProp; 12 | }; 13 | -------------------------------------------------------------------------------- /src/components/LinearGradient/LinearGradientTypes.ts: -------------------------------------------------------------------------------- 1 | import type { ColorValue } from 'react-native'; 2 | import type { AnimatedStyleProp } from '..'; 3 | 4 | export type LinearGradientProps = { 5 | animatedStyles: AnimatedStyleProp; 6 | children?: JSX.Element; 7 | angle?: number; 8 | gradientRadialRadius?: number; 9 | gradientColoroffset?: string[]; 10 | gradientColors?: ColorValue[]; 11 | gradientButtonHeight?: number; 12 | gradientName?: string; 13 | }; 14 | -------------------------------------------------------------------------------- /example/android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | -------------------------------------------------------------------------------- /example/ios/.xcode.env: -------------------------------------------------------------------------------- 1 | # This `.xcode.env` file is versioned and is used to source the environment 2 | # used when running script phases inside Xcode. 3 | # To customize your local environment, you can create an `.xcode.env.local` 4 | # file that is not versioned. 5 | 6 | # NODE_BINARY variable contains the PATH to the node executable. 7 | # 8 | # Customize the NODE_BINARY variable here. 9 | # For example, to use nvm with brew, add the following line 10 | # . "$(brew --prefix nvm)/nvm.sh" --no-use 11 | export NODE_BINARY=$(command -v node) 12 | -------------------------------------------------------------------------------- /src/utils/index.tsx: -------------------------------------------------------------------------------- 1 | export { default as getPercentageFromAngle } from './getPercentageFromAngle'; 2 | export { default as useAnimatedValues } from './useAnimatedValues'; 3 | export { default as useRippleButton } from './useRippleButton'; 4 | export { 5 | DEFAULT_COLOR_WHITE, 6 | DEFAULT_ANIMATION_TYPE, 7 | getSpinnerStyle, 8 | getWaveFactorAndMode, 9 | } from './SpinnerUtils'; 10 | export { 11 | CoOrdinateProp, 12 | GradientDataProp, 13 | ColorListProp, 14 | getColorList, 15 | getGradientFromName, 16 | getAnglePercentageObject, 17 | } from './getAnglePercentageObject'; 18 | -------------------------------------------------------------------------------- /src/components/RadialGradient/RadialGradientTypes.ts: -------------------------------------------------------------------------------- 1 | import type { ColorValue } from 'react-native'; 2 | import type { AnimatedStyleProp } from '..'; 3 | 4 | export type RadialGradientProps = { 5 | animatedStyles: AnimatedStyleProp; 6 | children?: JSX.Element; 7 | gradientRadialRadius?: number; 8 | gradientColoroffset?: string[]; 9 | gradientColors?: ColorValue[]; 10 | gradientButtonHeight?: number; 11 | gradientName?: string; 12 | radialRadiusRX?: string | number; 13 | radialRadiusRY?: string | number; 14 | radialRadiusx?: string | number; 15 | radialRadiusy?: string | number; 16 | }; 17 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | ext { 5 | buildToolsVersion = "33.0.0" 6 | minSdkVersion = 21 7 | compileSdkVersion = 33 8 | targetSdkVersion = 33 9 | 10 | // We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP. 11 | ndkVersion = "23.1.7779620" 12 | } 13 | repositories { 14 | google() 15 | mavenCentral() 16 | } 17 | dependencies { 18 | classpath("com.android.tools.build:gradle") 19 | classpath("com.facebook.react:react-native-gradle-plugin") 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: "🚀 Publish" 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | release: 10 | name: 🚀 Publish 11 | runs-on: macos-11 12 | steps: 13 | - name: 📚 checkout 14 | uses: actions/checkout@v4 15 | - name: 🟢 node 16 | uses: actions/setup-node@v4 17 | with: 18 | node-version: 18 19 | registry-url: https://registry.npmjs.org 20 | - name: 🚀 Build & Publish 21 | run: yarn install && yarn build && yarn publish --access public 22 | env: 23 | NODE_AUTH_TOKEN: ${{secrets.NPM_AUTH_TOKEN}} -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["@react-native-community", "prettier"], 3 | "root": true, 4 | "rules": { 5 | "prettier/prettier": [ 6 | "error", 7 | { 8 | "quoteProps": "preserve", 9 | "singleQuote": true, 10 | "tabWidth": 2, 11 | "trailingComma": "es5", 12 | "useTabs": false 13 | } 14 | ], 15 | "no-shadow": "off", 16 | "@typescript-eslint/no-shadow": ["error"], 17 | "no-bitwise": 0, 18 | "prefer-const": "warn", 19 | "no-console": ["error", { "allow": ["warn", "error"] }] 20 | }, 21 | "globals": { 22 | "JSX": "readonly" 23 | }, 24 | "env": { 25 | "jest": true 26 | }, 27 | "plugins": ["prettier"] 28 | } -------------------------------------------------------------------------------- /example/App/styles/AppStyles.tsx: -------------------------------------------------------------------------------- 1 | import {StyleSheet} from 'react-native'; 2 | 3 | export default StyleSheet.create({ 4 | safeArea: { 5 | backgroundColor: '#F5FCFF', 6 | marginTop: 70, 7 | }, 8 | container: { 9 | flex: 1, 10 | alignItems: 'center', 11 | backgroundColor: '#F5FCFF', 12 | }, 13 | buttonText: { 14 | fontSize: 20, 15 | textAlign: 'center', 16 | color: 'white', 17 | }, 18 | buttonStyle: { 19 | borderRadius: 10, 20 | margin: 5, 21 | }, 22 | instructions: { 23 | textAlign: 'center', 24 | color: '#333333', 25 | marginBottom: 5, 26 | }, 27 | borderStyle: { 28 | borderWidth: 2, 29 | borderRadius: 10, 30 | borderColor: 'blue', 31 | borderStyle: 'solid', 32 | }, 33 | }); 34 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | We welcome code changes that improve this library or fix a problem, and please make sure to follow all best practices and test all the changes/fixes before committing and creating a pull request. 🚀 🚀 4 | 5 | ### Committing and Pushing Changes 6 | 7 | Commit messages should be formatted as: 8 | 9 | ``` 10 | [optional scope]: 11 | 12 | [optional body] 13 | 14 | [optional footer] 15 | ``` 16 | 17 | Where type can be one of the following: 18 | 19 | - feat 20 | - fix 21 | - docs 22 | - chore 23 | - style 24 | - refactor 25 | - test 26 | 27 | and an optional scope can be a component 28 | 29 | ``` 30 | docs: update contributing guide 31 | ``` 32 | 33 | ``` 34 | fix(TicketId/Component): layout flicker issue 35 | ``` -------------------------------------------------------------------------------- /example/android/app/src/release/java/com/example/ReactNativeFlipper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | *

This source code is licensed under the MIT license found in the LICENSE file in the root 5 | * directory of this source tree. 6 | */ 7 | package com.example; 8 | 9 | import android.content.Context; 10 | import com.facebook.react.ReactInstanceManager; 11 | 12 | /** 13 | * Class responsible of loading Flipper inside your React Native application. This is the release 14 | * flavor of it so it's empty as we don't want to load Flipper. 15 | */ 16 | public class ReactNativeFlipper { 17 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { 18 | // Do nothing as we don't want to initialize Flipper on Release. 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /example/App/RippleEffectButton.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StyleSheet, Text } from 'react-native'; 3 | import SpinnerButton from 'react-native-spinner-button'; 4 | import styles from './styles/AppStyles'; 5 | 6 | const RippleEffectButton: React.FC = () => { 7 | const buttonPress: () => void = () => { 8 | console.log('Button Clicked'); 9 | }; 10 | 11 | return ( 12 | 16 | RippleButton 17 | 18 | ); 19 | }; 20 | 21 | const style = StyleSheet.create({ 22 | btnStyle: { 23 | backgroundColor: '#893346', 24 | }, 25 | }); 26 | 27 | export default RippleEffectButton; 28 | -------------------------------------------------------------------------------- /example/ios/exampleTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/components/AnimatableView/AnimatableTypes.ts: -------------------------------------------------------------------------------- 1 | import type { ColorValue } from 'react-native'; 2 | import type { SpinnerOptionsProp } from '..'; 3 | 4 | export type SpinnerType = 5 | | 'BarIndicator' 6 | | 'DotIndicator' 7 | | 'MaterialIndicator' 8 | | 'PacmanIndicator' 9 | | 'PulseIndicator' 10 | | 'SkypeIndicator' 11 | | 'UIActivityIndicator' 12 | | 'WaveIndicator' 13 | | 'BallIndicator'; 14 | 15 | export type CommonViewProps = { 16 | children: JSX.Element; 17 | customSpinnerComponent?: JSX.Element; 18 | height: number; 19 | size: number; 20 | spinnerColor: ColorValue; 21 | spinnerType: SpinnerType; 22 | indicatorCount?: number; 23 | spinnerOptions?: SpinnerOptionsProp; 24 | }; 25 | 26 | export type AnimatableViewProps = CommonViewProps & { 27 | animationType: string; 28 | isLoading?: boolean; 29 | animatedDuration?: number; 30 | }; 31 | -------------------------------------------------------------------------------- /example/ios/example/AppDelegate.mm: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | #import 4 | 5 | @implementation AppDelegate 6 | 7 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 8 | { 9 | self.moduleName = @"example"; 10 | // You can add your custom initial props in the dictionary below. 11 | // They will be passed down to the ViewController used by React Native. 12 | self.initialProps = @{}; 13 | 14 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 15 | } 16 | 17 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge 18 | { 19 | #if DEBUG 20 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; 21 | #else 22 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 23 | #endif 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /src/styles/SpinnerButtonStyle.ts: -------------------------------------------------------------------------------- 1 | import { StyleSheet } from 'react-native'; 2 | 3 | export default StyleSheet.create({ 4 | buttonContainer: { 5 | flex: 1, 6 | }, 7 | button: { 8 | alignItems: 'center', 9 | justifyContent: 'center', 10 | height: 50, 11 | width: '100%', 12 | }, 13 | centerAlign: { 14 | justifyContent: 'center', 15 | alignItems: 'center', 16 | }, 17 | defaultButton: { 18 | height: 50, 19 | }, 20 | absoluteView: { 21 | ...StyleSheet.absoluteFillObject, 22 | }, 23 | defaultGradientContainerStyle: { 24 | width: '100%', 25 | }, 26 | animatedViewContainer: { 27 | marginTop: 0, 28 | marginBottom: 0, 29 | marginLeft: 0, 30 | marginRight: 0, 31 | paddingTop: 0, 32 | paddingBottom: 0, 33 | paddingLeft: 0, 34 | paddingRight: 0, 35 | }, 36 | rippleButtonStyle: { 37 | width: '100%', 38 | } 39 | }); 40 | -------------------------------------------------------------------------------- /example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "esModuleInterop": true, 5 | "jsx": "react-native", 6 | "lib": ["ESNext"], 7 | "module": "CommonJS", 8 | "noEmit": true, 9 | "paths": { 10 | "react-native-spinner-button": ["../src"] 11 | }, 12 | "declaration": true, 13 | "allowUnreachableCode": false, 14 | "allowUnusedLabels": false, 15 | "importsNotUsedAsValues": "error", 16 | "forceConsistentCasingInFileNames": true, 17 | "moduleResolution": "Node", 18 | "noFallthroughCasesInSwitch": true, 19 | "noImplicitReturns": true, 20 | "noImplicitUseStrict": false, 21 | "noStrictGenericChecks": false, 22 | "noUnusedLocals": true, 23 | "noUnusedParameters": true, 24 | "resolveJsonModule": true, 25 | "noEmitOnError": true, 26 | "skipLibCheck": true, 27 | "sourceMap": true, 28 | "strict": true, 29 | "target": "ES2018" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/components/ChildrenView/ChildrenViewTypes.ts: -------------------------------------------------------------------------------- 1 | import type { Animated, ColorValue } from 'react-native'; 2 | import type { GradientType } from '../SpinnerButton'; 3 | 4 | export type AnimatedStyleProp = { 5 | width: Animated.AnimatedInterpolation; 6 | borderRadius: Animated.AnimatedInterpolation; 7 | height: Animated.AnimatedInterpolation; 8 | elevation: number; 9 | overflow: string; 10 | }; 11 | 12 | export type ChildrenViewProps = { 13 | animatedStyles: AnimatedStyleProp; 14 | gradientType?: GradientType; 15 | gradientColors?: ColorValue[]; 16 | gradientColoroffset?: string[]; 17 | gradientColorAngle?: number; 18 | gradientRadialRadius?: number; 19 | gradientButtonHeight?: number; 20 | radialRadiusx?: string | number; 21 | radialRadiusy?: string | number; 22 | radialRadiusRX?: string | number; 23 | radialRadiusRY?: string | number; 24 | children: JSX.Element; 25 | gradientName?: string; 26 | }; 27 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "declaration": true, 5 | "esModuleInterop": true, 6 | "allowUnreachableCode": false, 7 | "allowUnusedLabels": false, 8 | "jsx": "react", 9 | "lib": ["ESNext"], 10 | "module": "ESNext", 11 | "importsNotUsedAsValues": "error", 12 | "forceConsistentCasingInFileNames": true, 13 | "moduleResolution": "Node", 14 | "noFallthroughCasesInSwitch": true, 15 | "noImplicitReturns": false, 16 | "noImplicitUseStrict": false, 17 | "noStrictGenericChecks": false, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "resolveJsonModule": true, 21 | "noEmitOnError": true, 22 | "outDir": "./lib", 23 | "skipLibCheck": true, 24 | "sourceMap": true, 25 | "strict": true, 26 | "target": "ESNext", 27 | }, 28 | "exclude": ["example/node_modules/**", "node_modules/**", "**/__tests__/*"], 29 | "include": ["src", "src/utils/*.json"] 30 | } 31 | -------------------------------------------------------------------------------- /example/App/PulseSpinnerButton.tsx: -------------------------------------------------------------------------------- 1 | import React, {useCallback, useState} from 'react'; 2 | import {StyleSheet, Text} from 'react-native'; 3 | import SpinnerButton from 'react-native-spinner-button'; 4 | import styles from './styles/AppStyles'; 5 | 6 | const PulseSpinnerButton: React.FC = () => { 7 | const [isLoading, setLoading] = useState(false); 8 | 9 | const handleButtonPress = useCallback<() => void>(() => { 10 | setLoading(true); 11 | setTimeout(() => { 12 | setLoading(false); 13 | }, 3000); 14 | }, []); 15 | 16 | return ( 17 | 22 | Pulse SpinnerButton 23 | 24 | ); 25 | }; 26 | 27 | const style = StyleSheet.create({ 28 | btnStyle: { 29 | backgroundColor: '#4CA0F7', 30 | }, 31 | }); 32 | 33 | export default PulseSpinnerButton; 34 | -------------------------------------------------------------------------------- /example/App/MaterialSpinnerButton.tsx: -------------------------------------------------------------------------------- 1 | import React, {useCallback, useState} from 'react'; 2 | import {StyleSheet, Text} from 'react-native'; 3 | import SpinnerButton from 'react-native-spinner-button'; 4 | import styles from './styles/AppStyles'; 5 | 6 | const MaterialSpinnerButton: React.FC = () => { 7 | const [isLoading, setLoading] = useState(false); 8 | 9 | const handleButtonPress = useCallback<() => void>(() => { 10 | setLoading(true); 11 | setTimeout(() => { 12 | setLoading(false); 13 | }, 3000); 14 | }, []); 15 | 16 | return ( 17 | 22 | Material SpinnerButton 23 | 24 | ); 25 | }; 26 | 27 | const style = StyleSheet.create({ 28 | btnStyle: { 29 | backgroundColor: '#dead00', 30 | }, 31 | }); 32 | 33 | export default MaterialSpinnerButton; 34 | -------------------------------------------------------------------------------- /example/App/UIActivitySpinnerButton.tsx: -------------------------------------------------------------------------------- 1 | import React, {useCallback, useState} from 'react'; 2 | import {StyleSheet, Text} from 'react-native'; 3 | import SpinnerButton from 'react-native-spinner-button'; 4 | import styles from './styles/AppStyles'; 5 | 6 | const UIActivitySpinnerButton: React.FC = () => { 7 | const [isLoading, setLoading] = useState(false); 8 | 9 | const handleButtonPress = useCallback<() => void>(() => { 10 | setLoading(true); 11 | setTimeout(() => { 12 | setLoading(false); 13 | }, 3000); 14 | }, []); 15 | 16 | return ( 17 | 22 | UIActivity SpinnerButton 23 | 24 | ); 25 | }; 26 | 27 | const style = StyleSheet.create({ 28 | btnStyle: { 29 | backgroundColor: '#F87217', 30 | }, 31 | }); 32 | 33 | export default UIActivitySpinnerButton; 34 | -------------------------------------------------------------------------------- /example/App/WaveSpinnerButton.tsx: -------------------------------------------------------------------------------- 1 | import React, {useCallback, useState} from 'react'; 2 | import {StyleSheet, Text} from 'react-native'; 3 | import SpinnerButton from 'react-native-spinner-button'; 4 | import styles from './styles/AppStyles'; 5 | 6 | const WaveSpinnerButton: React.FC = () => { 7 | const [isLoading, setLoading] = useState(false); 8 | 9 | const handleButtonPress = useCallback<() => void>(() => { 10 | setLoading(true); 11 | setTimeout(() => { 12 | setLoading(false); 13 | }, 3000); 14 | }, []); 15 | 16 | return ( 17 | 25 | Wave SpinnerButton 26 | 27 | ); 28 | }; 29 | 30 | const style = StyleSheet.create({ 31 | btnStyle: { 32 | backgroundColor: '#9090ee', 33 | }, 34 | }); 35 | 36 | export default WaveSpinnerButton; 37 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 12 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /example/ios/example/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ios-marketing", 45 | "scale" : "1x", 46 | "size" : "1024x1024" 47 | } 48 | ], 49 | "info" : { 50 | "author" : "xcode", 51 | "version" : 1 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Simform Solutions 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | 24 | # Android/IntelliJ 25 | # 26 | build/ 27 | .idea 28 | .gradle 29 | local.properties 30 | *.iml 31 | 32 | # node.js 33 | # 34 | node_modules/ 35 | npm-debug.log 36 | yarn-error.log* 37 | yarn.lock 38 | package-lock.json 39 | 40 | # BUCK 41 | buck-out/ 42 | \.buckd/ 43 | *.keystore 44 | !debug.keystore 45 | 46 | # fastlane 47 | # 48 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 49 | # screenshots whenever they are needed. 50 | # For more information about the recommended setup visit: 51 | # https://docs.fastlane.tools/best-practices/source-control/ 52 | 53 | */fastlane/report.xml 54 | */fastlane/Preview.html 55 | */fastlane/screenshots 56 | 57 | # Bundle artifact 58 | *.jsbundle 59 | 60 | # Ruby / CocoaPods 61 | /ios/Pods/ 62 | /vendor/bundle/ 63 | coverage 64 | 65 | # generated 66 | lib -------------------------------------------------------------------------------- /example/App/BarSpinnerButton.tsx: -------------------------------------------------------------------------------- 1 | import React, {useCallback, useState} from 'react'; 2 | import {StyleSheet, Text} from 'react-native'; 3 | import SpinnerButton from 'react-native-spinner-button'; 4 | import styles from './styles/AppStyles'; 5 | 6 | const BarSpinnerButton: React.FC = () => { 7 | const [isLoading, setLoading] = useState(false); 8 | 9 | const handleButtonPress = useCallback<() => void>(() => { 10 | setLoading(true); 11 | setTimeout(() => { 12 | setLoading(false); 13 | }, 3000); 14 | }, []); 15 | 16 | return ( 17 | 28 | Bar SpinnerButton 29 | 30 | ); 31 | }; 32 | 33 | const style = StyleSheet.create({ 34 | btnStyle: { 35 | backgroundColor: '#1aafb8', 36 | }, 37 | }); 38 | 39 | export default BarSpinnerButton; 40 | -------------------------------------------------------------------------------- /example/App/App.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {ScrollView} from 'react-native'; 3 | import styles from './styles/AppStyles'; 4 | import DefaultOrBallSpinnerButton from './DefaultOrBallSpinnerButton'; 5 | import BarSpinnerButton from './BarSpinnerButton'; 6 | import DotSpinnerButton from './DotSpinnerButton'; 7 | import MaterialSpinnerButton from './MaterialSpinnerButton'; 8 | import PacmanSpinnerButton from './PacmanSpinnerButton'; 9 | import PulseSpinnerButton from './PulseSpinnerButton'; 10 | import SkypeSpinnerButton from './SkypeSpinnerButton'; 11 | import UIActivitySpinnerButton from './UIActivitySpinnerButton'; 12 | import WaveSpinnerButton from './WaveSpinnerButton'; 13 | import RippleEffectButton from './RippleEffectButton'; 14 | 15 | const App: React.FC = () => { 16 | return ( 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | ); 30 | }; 31 | 32 | export default App; 33 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/example/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import com.facebook.react.ReactActivity; 4 | import com.facebook.react.ReactActivityDelegate; 5 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint; 6 | import com.facebook.react.defaults.DefaultReactActivityDelegate; 7 | 8 | public class MainActivity extends ReactActivity { 9 | 10 | /** 11 | * Returns the name of the main component registered from JavaScript. This is used to schedule 12 | * rendering of the component. 13 | */ 14 | @Override 15 | protected String getMainComponentName() { 16 | return "example"; 17 | } 18 | 19 | /** 20 | * Returns the instance of the {@link ReactActivityDelegate}. Here we use a util class {@link 21 | * DefaultReactActivityDelegate} which allows you to easily enable Fabric and Concurrent React 22 | * (aka React 18) with two boolean flags. 23 | */ 24 | @Override 25 | protected ReactActivityDelegate createReactActivityDelegate() { 26 | return new DefaultReactActivityDelegate( 27 | this, 28 | getMainComponentName(), 29 | // If you opted-in for the New Architecture, we enable the Fabric Renderer. 30 | DefaultNewArchitectureEntryPoint.getFabricEnabled()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | ios/.xcode.env.local 24 | 25 | # Android/IntelliJ 26 | # 27 | build/ 28 | .idea 29 | .gradle 30 | local.properties 31 | *.iml 32 | *.hprof 33 | .cxx/ 34 | *.keystore 35 | !debug.keystore 36 | 37 | # node.js 38 | # 39 | node_modules/ 40 | npm-debug.log 41 | yarn-error.log 42 | yarn.lock 43 | package-lock.json 44 | 45 | # fastlane 46 | # 47 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 48 | # screenshots whenever they are needed. 49 | # For more information about the recommended setup visit: 50 | # https://docs.fastlane.tools/best-practices/source-control/ 51 | 52 | **/fastlane/report.xml 53 | **/fastlane/Preview.html 54 | **/fastlane/screenshots 55 | **/fastlane/test_output 56 | 57 | # Bundle artifact 58 | *.jsbundle 59 | 60 | # Ruby / CocoaPods 61 | /ios/Pods/ 62 | /vendor/bundle/ 63 | 64 | # Temporary files created by Metro to check the health of the file watcher 65 | .metro-health-check* 66 | 67 | # testing 68 | /coverage 69 | -------------------------------------------------------------------------------- /example/App/DefaultOrBallSpinnerButton.tsx: -------------------------------------------------------------------------------- 1 | import React, { useCallback, useState } from 'react'; 2 | import { StyleSheet, Text } from 'react-native'; 3 | import SpinnerButton from 'react-native-spinner-button'; 4 | import styles from './styles/AppStyles'; 5 | 6 | const DefaultOrBallSpinnerButton: React.FC = () => { 7 | const [isLoading, setLoading] = useState(false); 8 | 9 | const handleButtonPress = useCallback<() => void>(() => { 10 | setLoading(true); 11 | setTimeout(() => { 12 | setLoading(false); 13 | }, 3000); 14 | }, []); 15 | 16 | return ( 17 | 29 | Default Or Ball SpinnerButton 30 | 31 | ); 32 | }; 33 | 34 | const style = StyleSheet.create({ 35 | btnStyle: { 36 | backgroundColor: '#893346', 37 | }, 38 | }); 39 | 40 | export default DefaultOrBallSpinnerButton; 41 | -------------------------------------------------------------------------------- /example/App/PacmanSpinnerButton.tsx: -------------------------------------------------------------------------------- 1 | import React, { useCallback, useState } from 'react'; 2 | import { StyleSheet, Text } from 'react-native'; 3 | import SpinnerButton from 'react-native-spinner-button'; 4 | import styles from './styles/AppStyles'; 5 | 6 | const PacmanSpinnerButton: React.FC = () => { 7 | const [isLoading, setLoading] = useState(false); 8 | 9 | const handleButtonPress = useCallback<() => void>(() => { 10 | setLoading(true); 11 | setTimeout(() => { 12 | setLoading(false); 13 | }, 3000); 14 | }, []); 15 | 16 | return ( 17 | 31 | Pacman SpinnerButton 32 | 33 | ); 34 | }; 35 | 36 | const style = StyleSheet.create({ 37 | btnStyle: { 38 | backgroundColor: '#666666', 39 | }, 40 | }); 41 | 42 | export default PacmanSpinnerButton; 43 | -------------------------------------------------------------------------------- /example/App/SkypeSpinnerButton.tsx: -------------------------------------------------------------------------------- 1 | import React, { useCallback, useState } from 'react'; 2 | import { StyleSheet, Text } from 'react-native'; 3 | import SpinnerButton from 'react-native-spinner-button'; 4 | import styles from './styles/AppStyles'; 5 | 6 | const SkypeSpinnerButton: React.FC = () => { 7 | const [isLoading, setLoading] = useState(false); 8 | 9 | const handleButtonPress = useCallback<() => void>(() => { 10 | setLoading(true); 11 | setTimeout(() => { 12 | setLoading(false); 13 | }, 3000); 14 | }, []); 15 | 16 | return ( 17 | 32 | Skype SpinnerButton 33 | 34 | ); 35 | }; 36 | 37 | const style = StyleSheet.create({ 38 | btnStyle: { 39 | backgroundColor: '#123456', 40 | }, 41 | }); 42 | 43 | export default SkypeSpinnerButton; 44 | -------------------------------------------------------------------------------- /example/metro.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Metro configuration for React Native 3 | * https://github.com/facebook/react-native 4 | * 5 | * @format 6 | */ 7 | const path = require('path'); 8 | const rootPackage = require('../package.json'); 9 | const blacklist = require('metro-config/src/defaults/exclusionList'); 10 | const rootModules = Object.keys({ 11 | ...rootPackage.peerDependencies, 12 | }); 13 | const moduleRoot = path.resolve(__dirname, '..'); 14 | /** 15 | * Only load one version for peerDependencies and alias them to the versions in Example's node_modules" 16 | */ 17 | module.exports = { 18 | watchFolders: [moduleRoot], 19 | resolver: { 20 | blacklistRE: blacklist([ 21 | ...rootModules.map( 22 | m => 23 | new RegExp( 24 | `^${escape(path.join(moduleRoot, 'node_modules', m))}\\/.*$` 25 | ) 26 | ), 27 | /^((?!example).)+[\/\\]node_modules[/\\]react[/\\].*/, 28 | /^((?!example).)+[\/\\]node_modules[/\\]react-native[/\\].*/, 29 | ]), 30 | extraNodeModules: { 31 | ...rootModules.reduce((acc, name) => { 32 | acc[name] = path.join(__dirname, 'node_modules', name); 33 | return acc; 34 | }, {}), 35 | }, 36 | }, 37 | transformer: { 38 | getTransformOptions: async () => ({ 39 | transform: { 40 | experimentalImportSupport: false, 41 | inlineRequires: true, 42 | }, 43 | }), 44 | }, 45 | }; -------------------------------------------------------------------------------- /src/components/AnimatedView/AnimatedView.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Animated } from 'react-native'; 3 | import { SpinnerComponent } from '../../components'; 4 | import type { AnimatedViewProps } from './AnimatedTypes'; 5 | import { SpinnerButtonStyle } from '../../styles'; 6 | 7 | const AnimatedView: React.FC = ({ 8 | animatedChildHideStyle, 9 | animatedChildShowStyle, 10 | children, 11 | customSpinnerComponent, 12 | height, 13 | size, 14 | spinnerColor, 15 | spinnerType, 16 | indicatorCount, 17 | spinnerOptions, 18 | }: AnimatedViewProps) => { 19 | const isCustomeSpinner: boolean = 20 | customSpinnerComponent !== null && customSpinnerComponent !== undefined; 21 | return ( 22 | <> 23 | {children} 24 | 26 | {isCustomeSpinner && customSpinnerComponent} 27 | {!isCustomeSpinner && ( 28 | 36 | )} 37 | 38 | 39 | ); 40 | }; 41 | 42 | export default AnimatedView; 43 | -------------------------------------------------------------------------------- /example/App/DotSpinnerButton.tsx: -------------------------------------------------------------------------------- 1 | import React, {useCallback, useState} from 'react'; 2 | import {StyleSheet, Text} from 'react-native'; 3 | import SpinnerButton from 'react-native-spinner-button'; 4 | import styles from './styles/AppStyles'; 5 | 6 | const DotSpinnerButton: React.FC = () => { 7 | const [isLoading, setLoading] = useState(false); 8 | 9 | const handleButtonPress = useCallback<() => void>(() => { 10 | setLoading(true); 11 | setTimeout(() => { 12 | setLoading(false); 13 | }, 3000); 14 | }, []); 15 | 16 | return ( 17 | 37 | Dot SpinnerButton 38 | 39 | ); 40 | }; 41 | 42 | const style = StyleSheet.create({ 43 | btnStyle: { 44 | backgroundColor: '#bf57c3', 45 | }, 46 | }); 47 | 48 | export default DotSpinnerButton; 49 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "android": "react-native run-android", 7 | "ios": "react-native run-ios", 8 | "start": "react-native start", 9 | "test": "jest", 10 | "lint": "eslint . --ext .js,.jsx,.ts,.tsx" 11 | }, 12 | "dependencies": { 13 | "react": "18.2.0", 14 | "react-native": "0.72.10", 15 | "react-native-gradients": "^2.1.1", 16 | "react-native-svg": "^14.1.0" 17 | }, 18 | "devDependencies": { 19 | "@babel/core": "^7.20.0", 20 | "@babel/preset-env": "^7.20.0", 21 | "@babel/runtime": "^7.20.0", 22 | "@react-native-community/eslint-config": "^3.0.1", 23 | "@react-native/metro-config": "^0.72.11", 24 | "@tsconfig/react-native": "^3.0.0", 25 | "@types/react": "^18.0.24", 26 | "@types/react-test-renderer": "^18.0.0", 27 | "babel-jest": "^29.2.1", 28 | "@typescript-eslint/eslint-plugin": "^5.29.0", 29 | "@typescript-eslint/parser": "^5.29.0", 30 | "eslint": "^8", 31 | "eslint-plugin-prettier": "^5.1.3", 32 | "eslint-plugin-simple-import-sort": "^12.0.0", 33 | "jest": "^29.2.1", 34 | "metro-react-native-babel-preset": "0.76.8", 35 | "react-test-renderer": "18.2.0", 36 | "typescript": "4.8.4" 37 | }, 38 | "engines": { 39 | "node": ">=16" 40 | }, 41 | "jest": { 42 | "preset": "react-native", 43 | "moduleFileExtensions": [ 44 | "ts", 45 | "tsx", 46 | "js", 47 | "jsx", 48 | "json", 49 | "node" 50 | ] 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/components/AnimatableView/AnimatableView.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import * as Animatable from 'react-native-animatable'; 3 | import { SpinnerComponent } from '../../components'; 4 | import type { AnimatableViewProps } from './AnimatableTypes'; 5 | import { SpinnerButtonStyle } from '../../styles'; 6 | 7 | const AnimatableView: React.FC = ({ 8 | animationType, 9 | children, 10 | customSpinnerComponent, 11 | height, 12 | size, 13 | spinnerColor, 14 | spinnerType, 15 | indicatorCount, 16 | spinnerOptions, 17 | isLoading, 18 | animatedDuration, 19 | }: AnimatableViewProps) => { 20 | const isCustomeSpinner: boolean = 21 | customSpinnerComponent !== null && customSpinnerComponent !== undefined; 22 | return ( 23 | <> 24 | {!isLoading && ( 25 | 26 | {children} 27 | 28 | )} 29 | {isLoading && ( 30 | 34 | {isCustomeSpinner && customSpinnerComponent} 35 | {!isCustomeSpinner && ( 36 | 44 | )} 45 | 46 | )} 47 | 48 | ); 49 | }; 50 | 51 | export default AnimatableView; 52 | -------------------------------------------------------------------------------- /src/utils/SpinnerUtils.tsx: -------------------------------------------------------------------------------- 1 | import { StyleSheet, Dimensions } from 'react-native'; 2 | import type { StyleProp, ViewStyle, ColorValue } from 'react-native'; 3 | import type { SpinnerOptionsProp, waveModeType } from '../components'; 4 | 5 | const DEFAULT_COLOR_WHITE: ColorValue = 'rgb(255, 255, 255)'; 6 | const DEFAULT_ANIMATION_TYPE: string = 'fadeIn'; 7 | 8 | const defaulButtonWidth: number = Dimensions.get('window').width; 9 | const defaulButtonHeight: number = 50; 10 | 11 | const getSpinnerStyle = ( 12 | buttonStyle: StyleProp, 13 | defaultStyle: StyleProp 14 | ): { height: number } => { 15 | const customButtonStyle: ViewStyle = StyleSheet.flatten(buttonStyle); 16 | const defaultButtonStyle: ViewStyle = StyleSheet.flatten(defaultStyle); 17 | const height: number = 18 | typeof customButtonStyle.height === 'number' 19 | ? customButtonStyle.height 20 | : typeof defaultButtonStyle?.height === 'number' 21 | ? defaultButtonStyle.height 22 | : 50; 23 | return { height }; 24 | }; 25 | 26 | const getWaveFactorAndMode = ( 27 | spinnerOptions: SpinnerOptionsProp | undefined 28 | ): SpinnerOptionsProp => { 29 | let waveFactor: number = 0.54; 30 | let waveMode: waveModeType = 'fill'; 31 | if (spinnerOptions !== undefined && spinnerOptions.waveFactor !== undefined) { 32 | waveFactor = spinnerOptions.waveFactor; 33 | } 34 | if (spinnerOptions !== undefined && spinnerOptions.waveMode !== undefined) { 35 | waveMode = spinnerOptions.waveMode; 36 | } 37 | return { waveFactor, waveMode }; 38 | }; 39 | 40 | export { 41 | defaulButtonWidth, 42 | defaulButtonHeight, 43 | DEFAULT_COLOR_WHITE, 44 | DEFAULT_ANIMATION_TYPE, 45 | getSpinnerStyle, 46 | getWaveFactorAndMode, 47 | }; 48 | -------------------------------------------------------------------------------- /example/ios/example/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | example 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(MARKETING_VERSION) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(CURRENT_PROJECT_VERSION) 25 | LSRequiresIPhoneOS 26 | 27 | NSAppTransportSecurity 28 | 29 | NSExceptionDomains 30 | 31 | localhost 32 | 33 | NSExceptionAllowsInsecureHTTPLoads 34 | 35 | 36 | 37 | 38 | NSLocationWhenInUseUsageDescription 39 | 40 | UILaunchStoryboardName 41 | LaunchScreen 42 | UIRequiredDeviceCapabilities 43 | 44 | armv7 45 | 46 | UISupportedInterfaceOrientations 47 | 48 | UIInterfaceOrientationPortrait 49 | UIInterfaceOrientationLandscapeLeft 50 | UIInterfaceOrientationLandscapeRight 51 | 52 | UIViewControllerBasedStatusBarAppearance 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /src/components/ChildrenView/ChildrenView.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { LinearGradient, RadialGradient } from '../../components'; 3 | import type { ChildrenViewProps } from './ChildrenViewTypes'; 4 | 5 | const ChildrenView: React.FC = ({ 6 | animatedStyles, 7 | gradientType, 8 | gradientColors, 9 | gradientColoroffset, 10 | gradientColorAngle, 11 | gradientRadialRadius, 12 | gradientButtonHeight, 13 | radialRadiusx, 14 | radialRadiusy, 15 | radialRadiusRX, 16 | radialRadiusRY, 17 | children, 18 | gradientName, 19 | }: ChildrenViewProps) => { 20 | const isLinearGradient: boolean = 21 | gradientType?.trim()?.toLowerCase() === 'linear'; 22 | const isRadialGradient: boolean = 23 | gradientType?.trim()?.toLowerCase() === 'radial'; 24 | 25 | if (isLinearGradient) { 26 | return ( 27 | 37 | ); 38 | } else if (isRadialGradient) { 39 | return ( 40 | 53 | ); 54 | } else { 55 | return children; 56 | } 57 | }; 58 | 59 | export default ChildrenView; 60 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/rn_edit_text_material.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 21 | 22 | 23 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m 13 | org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | # AndroidX package structure to make it clearer which packages are bundled with the 21 | # Android operating system, and which are packaged with your app's APK 22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 23 | android.useAndroidX=true 24 | # Automatically convert third-party libraries to use AndroidX 25 | android.enableJetifier=true 26 | 27 | # Version of flipper SDK to use with React Native 28 | FLIPPER_VERSION=0.182.0 29 | 30 | # Use this property to specify which architecture you want to build. 31 | # You can also override it from the CLI using 32 | # ./gradlew -PreactNativeArchitectures=x86_64 33 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64 34 | 35 | # Use this property to enable support to the new architecture. 36 | # This will allow you to use TurboModules and the Fabric render in 37 | # your application. You should enable this flag either if you want 38 | # to write custom TurboModules/Fabric components OR use libraries that 39 | # are providing them. 40 | newArchEnabled=false 41 | 42 | # Use this property to enable or disable the Hermes JS engine. 43 | # If set to false, you will be using JSC instead. 44 | hermesEnabled=true 45 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/example/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import android.app.Application; 4 | import com.facebook.react.PackageList; 5 | import com.facebook.react.ReactApplication; 6 | import com.facebook.react.ReactNativeHost; 7 | import com.facebook.react.ReactPackage; 8 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint; 9 | import com.facebook.react.defaults.DefaultReactNativeHost; 10 | import com.facebook.soloader.SoLoader; 11 | import java.util.List; 12 | 13 | public class MainApplication extends Application implements ReactApplication { 14 | 15 | private final ReactNativeHost mReactNativeHost = 16 | new DefaultReactNativeHost(this) { 17 | @Override 18 | public boolean getUseDeveloperSupport() { 19 | return BuildConfig.DEBUG; 20 | } 21 | 22 | @Override 23 | protected List getPackages() { 24 | @SuppressWarnings("UnnecessaryLocalVariable") 25 | List packages = new PackageList(this).getPackages(); 26 | // Packages that cannot be autolinked yet can be added manually here, for example: 27 | // packages.add(new MyReactNativePackage()); 28 | return packages; 29 | } 30 | 31 | @Override 32 | protected String getJSMainModuleName() { 33 | return "index"; 34 | } 35 | 36 | @Override 37 | protected boolean isNewArchEnabled() { 38 | return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED; 39 | } 40 | 41 | @Override 42 | protected Boolean isHermesEnabled() { 43 | return BuildConfig.IS_HERMES_ENABLED; 44 | } 45 | }; 46 | 47 | @Override 48 | public ReactNativeHost getReactNativeHost() { 49 | return mReactNativeHost; 50 | } 51 | 52 | @Override 53 | public void onCreate() { 54 | super.onCreate(); 55 | SoLoader.init(this, /* native exopackage */ false); 56 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { 57 | // If you opted-in for the New Architecture, we load the native entry point for this app. 58 | DefaultNewArchitectureEntryPoint.load(); 59 | } 60 | ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /example/ios/exampleTests/ExampleTests.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | #import 5 | #import 6 | 7 | #define TIMEOUT_SECONDS 600 8 | #define TEXT_TO_LOOK_FOR @"Welcome to React" 9 | 10 | @interface exampleTests : XCTestCase 11 | 12 | @end 13 | 14 | @implementation exampleTests 15 | 16 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL (^)(UIView *view))test 17 | { 18 | if (test(view)) { 19 | return YES; 20 | } 21 | for (UIView *subview in [view subviews]) { 22 | if ([self findSubviewInView:subview matching:test]) { 23 | return YES; 24 | } 25 | } 26 | return NO; 27 | } 28 | 29 | - (void)testRendersWelcomeScreen 30 | { 31 | UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController]; 32 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; 33 | BOOL foundElement = NO; 34 | 35 | __block NSString *redboxError = nil; 36 | #ifdef DEBUG 37 | RCTSetLogFunction( 38 | ^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { 39 | if (level >= RCTLogLevelError) { 40 | redboxError = message; 41 | } 42 | }); 43 | #endif 44 | 45 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { 46 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 47 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 48 | 49 | foundElement = [self findSubviewInView:vc.view 50 | matching:^BOOL(UIView *view) { 51 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { 52 | return YES; 53 | } 54 | return NO; 55 | }]; 56 | } 57 | 58 | #ifdef DEBUG 59 | RCTSetLogFunction(RCTDefaultLogFunction); 60 | #endif 61 | 62 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); 63 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); 64 | } 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Resolve react_native_pods.rb with node to allow for hoisting 2 | require Pod::Executable.execute_command('node', ['-p', 3 | 'require.resolve( 4 | "react-native/scripts/react_native_pods.rb", 5 | {paths: [process.argv[1]]}, 6 | )', __dir__]).strip 7 | 8 | platform :ios, min_ios_version_supported 9 | prepare_react_native_project! 10 | 11 | # If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set. 12 | # because `react-native-flipper` depends on (FlipperKit,...) that will be excluded 13 | # 14 | # To fix this you can also exclude `react-native-flipper` using a `react-native.config.js` 15 | # ```js 16 | # module.exports = { 17 | # dependencies: { 18 | # ...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}), 19 | # ``` 20 | flipper_config = ENV['NO_FLIPPER'] == "1" ? FlipperConfiguration.disabled : FlipperConfiguration.enabled 21 | 22 | linkage = ENV['USE_FRAMEWORKS'] 23 | if linkage != nil 24 | Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green 25 | use_frameworks! :linkage => linkage.to_sym 26 | end 27 | 28 | target 'example' do 29 | config = use_native_modules! 30 | 31 | # Flags change depending on the env values. 32 | flags = get_default_flags() 33 | 34 | use_react_native!( 35 | :path => config[:reactNativePath], 36 | # Hermes is now enabled by default. Disable by setting this flag to false. 37 | :hermes_enabled => flags[:hermes_enabled], 38 | :fabric_enabled => flags[:fabric_enabled], 39 | # Enables Flipper. 40 | # 41 | # Note that if you have use_frameworks! enabled, Flipper will not work and 42 | # you should disable the next line. 43 | :flipper_configuration => flipper_config, 44 | # An absolute path to your application root. 45 | :app_path => "#{Pod::Config.instance.installation_root}/.." 46 | ) 47 | 48 | target 'exampleTests' do 49 | inherit! :complete 50 | # Pods for testing 51 | end 52 | 53 | post_install do |installer| 54 | # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202 55 | react_native_post_install( 56 | installer, 57 | config[:reactNativePath], 58 | :mac_catalyst_enabled => false 59 | ) 60 | __apply_Xcode_12_5_M1_post_install_workaround(installer) 61 | end 62 | end 63 | -------------------------------------------------------------------------------- /src/components/RadialGradient/RadialGradient.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Animated, View } from 'react-native'; 3 | import Svg, { 4 | Defs, 5 | RadialGradient as SVGRadialGradient, 6 | Rect, 7 | Stop, 8 | } from 'react-native-svg'; 9 | import { getGradientFromName, getColorList } from '../../utils'; 10 | import type { ColorListProp, GradientDataProp } from '../../utils'; 11 | import type { RadialGradientProps } from './RadialGradientTypes'; 12 | import { SpinnerButtonStyle } from '../../styles'; 13 | 14 | const AnimatedRect: Animated.AnimatedComponent = 15 | Animated.createAnimatedComponent(Rect); 16 | 17 | const RadialGradient: React.FC = ({ 18 | animatedStyles, 19 | children, 20 | gradientRadialRadius, 21 | gradientColoroffset = [], 22 | gradientColors = [], 23 | gradientButtonHeight, 24 | radialRadiusx, 25 | radialRadiusy, 26 | radialRadiusRX, 27 | radialRadiusRY, 28 | gradientName, 29 | }: RadialGradientProps) => { 30 | const rectWidth: Animated.AnimatedInterpolation | number = 31 | animatedStyles.width; 32 | const gradientData: GradientDataProp | null = gradientName 33 | ? getGradientFromName(gradientName) 34 | : null; 35 | const colorList: ColorListProp[] = getColorList( 36 | gradientData?.offset || gradientColoroffset, 37 | gradientData?.colors || gradientColors 38 | ); 39 | return ( 40 | 46 | 47 | 48 | 49 | 56 | {colorList.map((value, index) => ( 57 | 63 | ))} 64 | 65 | 66 | 74 | 75 | 76 | {children} 77 | 78 | ); 79 | }; 80 | 81 | export default RadialGradient; 82 | -------------------------------------------------------------------------------- /example/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | CFPropertyList (3.0.6) 5 | rexml 6 | activesupport (6.1.7.6) 7 | concurrent-ruby (~> 1.0, >= 1.0.2) 8 | i18n (>= 1.6, < 2) 9 | minitest (>= 5.1) 10 | tzinfo (~> 2.0) 11 | zeitwerk (~> 2.3) 12 | addressable (2.8.6) 13 | public_suffix (>= 2.0.2, < 6.0) 14 | algoliasearch (1.27.5) 15 | httpclient (~> 2.8, >= 2.8.3) 16 | json (>= 1.5.1) 17 | atomos (0.1.3) 18 | claide (1.1.0) 19 | cocoapods (1.15.2) 20 | addressable (~> 2.8) 21 | claide (>= 1.0.2, < 2.0) 22 | cocoapods-core (= 1.15.2) 23 | cocoapods-deintegrate (>= 1.0.3, < 2.0) 24 | cocoapods-downloader (>= 2.1, < 3.0) 25 | cocoapods-plugins (>= 1.0.0, < 2.0) 26 | cocoapods-search (>= 1.0.0, < 2.0) 27 | cocoapods-trunk (>= 1.6.0, < 2.0) 28 | cocoapods-try (>= 1.1.0, < 2.0) 29 | colored2 (~> 3.1) 30 | escape (~> 0.0.4) 31 | fourflusher (>= 2.3.0, < 3.0) 32 | gh_inspector (~> 1.0) 33 | molinillo (~> 0.8.0) 34 | nap (~> 1.0) 35 | ruby-macho (>= 2.3.0, < 3.0) 36 | xcodeproj (>= 1.23.0, < 2.0) 37 | cocoapods-core (1.15.2) 38 | activesupport (>= 5.0, < 8) 39 | addressable (~> 2.8) 40 | algoliasearch (~> 1.0) 41 | concurrent-ruby (~> 1.1) 42 | fuzzy_match (~> 2.0.4) 43 | nap (~> 1.0) 44 | netrc (~> 0.11) 45 | public_suffix (~> 4.0) 46 | typhoeus (~> 1.0) 47 | cocoapods-deintegrate (1.0.5) 48 | cocoapods-downloader (2.1) 49 | cocoapods-plugins (1.0.0) 50 | nap 51 | cocoapods-search (1.0.1) 52 | cocoapods-trunk (1.6.0) 53 | nap (>= 0.8, < 2.0) 54 | netrc (~> 0.11) 55 | cocoapods-try (1.2.0) 56 | colored2 (3.1.2) 57 | concurrent-ruby (1.2.3) 58 | escape (0.0.4) 59 | ethon (0.16.0) 60 | ffi (>= 1.15.0) 61 | ffi (1.16.3) 62 | fourflusher (2.3.1) 63 | fuzzy_match (2.0.4) 64 | gh_inspector (1.1.3) 65 | httpclient (2.8.3) 66 | i18n (1.14.1) 67 | concurrent-ruby (~> 1.0) 68 | json (2.7.1) 69 | minitest (5.22.2) 70 | molinillo (0.8.0) 71 | nanaimo (0.3.0) 72 | nap (1.1.0) 73 | netrc (0.11.0) 74 | public_suffix (4.0.7) 75 | rexml (3.2.6) 76 | ruby-macho (2.5.1) 77 | typhoeus (1.4.1) 78 | ethon (>= 0.9.0) 79 | tzinfo (2.0.6) 80 | concurrent-ruby (~> 1.0) 81 | xcodeproj (1.24.0) 82 | CFPropertyList (>= 2.3.3, < 4.0) 83 | atomos (~> 0.1.3) 84 | claide (>= 1.0.2, < 2.0) 85 | colored2 (~> 3.1) 86 | nanaimo (~> 0.3.0) 87 | rexml (~> 3.2.4) 88 | zeitwerk (2.6.13) 89 | 90 | PLATFORMS 91 | ruby 92 | 93 | DEPENDENCIES 94 | activesupport (>= 6.1.7.3, < 7.1.0) 95 | cocoapods (~> 1.13) 96 | 97 | RUBY VERSION 98 | ruby 2.6.10p210 99 | 100 | BUNDLED WITH 101 | 1.17.2 102 | -------------------------------------------------------------------------------- /src/utils/useRippleButton.ts: -------------------------------------------------------------------------------- 1 | import { useRef, useState } from 'react'; 2 | import { 3 | Animated, 4 | GestureResponderEvent, 5 | LayoutChangeEvent 6 | } from 'react-native'; 7 | 8 | type RippleButtonProp = { 9 | onPress: () => void; 10 | animatedDuration?: number; 11 | }; 12 | 13 | const useRippleButton = ({ onPress, animatedDuration }: RippleButtonProp) => { 14 | const translation: Animated.Value = useRef(new Animated.Value(0)).current; 15 | const touchX: Animated.Value = useRef(new Animated.Value(0)).current; 16 | const touchY: Animated.Value = useRef(new Animated.Value(0)).current; 17 | const [circleRadius, setCircleRadius] = useState(0); 18 | 19 | const handleRipplePress: (event: GestureResponderEvent) => void = ( 20 | event: GestureResponderEvent 21 | ) => { 22 | const { locationX, locationY } = event.nativeEvent; 23 | 24 | touchX.setValue(locationX - 5); 25 | touchY.setValue(locationY - 5); 26 | onPress?.(); 27 | 28 | Animated.timing(translation, { 29 | toValue: 1, 30 | duration: animatedDuration, 31 | useNativeDriver: false, 32 | }).start(() => { 33 | translation.setValue(0); 34 | }); 35 | }; 36 | 37 | const handleRippleLayout: (event: LayoutChangeEvent) => void = ( 38 | event: LayoutChangeEvent 39 | ) => { 40 | const { width, height } = event.nativeEvent.layout; 41 | setCircleRadius(Math.sqrt(width ** 2 + height ** 2)); 42 | }; 43 | 44 | const width: Animated.AnimatedInterpolation = translation.interpolate( 45 | { 46 | inputRange: [0, 1], 47 | outputRange: [1, circleRadius * 2], 48 | } 49 | ); 50 | const height: Animated.AnimatedInterpolation = 51 | translation.interpolate({ 52 | inputRange: [0, 1], 53 | outputRange: [1, circleRadius * 2], 54 | }); 55 | const opacity: Animated.AnimatedInterpolation = 56 | translation.interpolate({ 57 | inputRange: [0, 1], 58 | outputRange: [1, 0], 59 | }); 60 | 61 | const translateX: Animated.AnimatedInterpolation = 62 | translation.interpolate({ 63 | inputRange: [0, 1], 64 | outputRange: [1, -circleRadius], 65 | }); 66 | 67 | const translateY: Animated.AnimatedInterpolation = 68 | translation.interpolate({ 69 | inputRange: [0, 1], 70 | outputRange: [1, -circleRadius], 71 | }); 72 | 73 | const scale: number = 1; 74 | 75 | return { 76 | handleRipplePress, 77 | handleRippleLayout, 78 | animatedStyle: { 79 | width, 80 | height, 81 | opacity, 82 | transform: [{ translateX }, { translateY }, { scale }], 83 | borderRadius: circleRadius, 84 | top: touchY, 85 | left: touchX, 86 | }, 87 | }; 88 | }; 89 | 90 | export default useRippleButton; 91 | -------------------------------------------------------------------------------- /src/components/LinearGradient/LinearGradient.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Animated, View } from 'react-native'; 3 | import Svg, { 4 | Defs, 5 | LinearGradient as SVGLinearGradient, 6 | Rect, 7 | Stop, 8 | } from 'react-native-svg'; 9 | import { 10 | getColorList, 11 | getAnglePercentageObject, 12 | getGradientFromName, 13 | } from '../../utils'; 14 | import type { 15 | CoOrdinateProp, 16 | ColorListProp, 17 | GradientDataProp, 18 | } from '../../utils'; 19 | import type { LinearGradientProps } from './LinearGradientTypes'; 20 | import { SpinnerButtonStyle } from '../../styles'; 21 | 22 | const AnimatedRect: Animated.AnimatedComponent = 23 | Animated.createAnimatedComponent(Rect); 24 | 25 | const LinearGradient: React.FC = ({ 26 | animatedStyles, 27 | children, 28 | angle, 29 | gradientRadialRadius, 30 | gradientColoroffset = [], 31 | gradientColors = [], 32 | gradientButtonHeight, 33 | gradientName, 34 | }: LinearGradientProps) => { 35 | const rectWidth: Animated.AnimatedInterpolation = 36 | animatedStyles.width; 37 | const gradientData: GradientDataProp | null = gradientName 38 | ? getGradientFromName(gradientName) 39 | : null; 40 | const angleObj: CoOrdinateProp = 41 | typeof gradientData?.angle === 'number' 42 | ? getAnglePercentageObject(gradientData?.angle) 43 | : typeof angle === 'number' 44 | ? getAnglePercentageObject(angle) 45 | : { 46 | x1: 0, 47 | x2: 0, 48 | y1: 0, 49 | y2: 0, 50 | }; 51 | const colorList: ColorListProp[] = getColorList( 52 | gradientData?.offset || gradientColoroffset, 53 | gradientData?.colors || gradientColors 54 | ); 55 | return ( 56 | 62 | 63 | 64 | 65 | 71 | {colorList.map((value, index) => ( 72 | 78 | ))} 79 | 80 | 81 | 90 | 91 | 92 | {children ? children : <>} 93 | 94 | ); 95 | }; 96 | 97 | export default LinearGradient; 98 | -------------------------------------------------------------------------------- /src/utils/getAnglePercentageObject.tsx: -------------------------------------------------------------------------------- 1 | import type { ColorValue } from 'react-native'; 2 | import { getPercentageFromAngle } from '../utils'; 3 | 4 | export type CoOrdinateProp = { 5 | x1: number; 6 | x2: number; 7 | y1: number; 8 | y2: number; 9 | }; 10 | 11 | export type GradientDataProp = { 12 | name: string; 13 | angle: number; 14 | colors: ColorValue[]; 15 | offset: string[]; 16 | }; 17 | 18 | export type ColorListProp = { 19 | offset?: string; 20 | color?: ColorValue; 21 | opacity: string; 22 | }; 23 | 24 | const getAnglePercentageObject = (angle: number): CoOrdinateProp => { 25 | let realAngle: number = angle; 26 | let angleObj: CoOrdinateProp = { 27 | x1: 0, 28 | x2: 0, 29 | y1: 0, 30 | y2: 0, 31 | }; 32 | 33 | if (realAngle <= 45) { 34 | realAngle += 360; 35 | } 36 | 37 | if (realAngle > 45 && realAngle <= 135) { 38 | angleObj = { 39 | x1: getPercentageFromAngle(realAngle, 45), 40 | x2: getPercentageFromAngle(realAngle, 45, true), 41 | y1: 100, 42 | y2: 0, 43 | }; 44 | } else if (realAngle > 135 && realAngle <= 225) { 45 | angleObj = { 46 | x1: 100, 47 | x2: 0, 48 | y1: getPercentageFromAngle(realAngle, 135, true), 49 | y2: getPercentageFromAngle(realAngle, 135), 50 | }; 51 | } else if (realAngle > 225 && realAngle <= 315) { 52 | angleObj = { 53 | x1: getPercentageFromAngle(realAngle, 225, true), 54 | x2: getPercentageFromAngle(realAngle, 225), 55 | y1: 0, 56 | y2: 100, 57 | }; 58 | } else if (realAngle > 315) { 59 | angleObj = { 60 | x1: 0, 61 | x2: 100, 62 | y1: getPercentageFromAngle(realAngle, 315), 63 | y2: getPercentageFromAngle(realAngle, 315, true), 64 | }; 65 | } 66 | 67 | return angleObj; 68 | }; 69 | 70 | const getGradientFromName = (gradientName: string): GradientDataProp | null => { 71 | if ( 72 | gradientName !== null && 73 | gradientName !== undefined && 74 | gradientName !== '' 75 | ) { 76 | const gradientJson: GradientDataProp[] = require('./GradientData.json'); 77 | const gradientObject: GradientDataProp[] = gradientJson.filter( 78 | (item: { name: string }) => 79 | item.name.trim().toLowerCase() === gradientName.trim().toLowerCase() 80 | ); 81 | if (gradientObject.length > 0) { 82 | return gradientObject[0]; 83 | } 84 | } 85 | return null; 86 | }; 87 | 88 | const getColorList = ( 89 | gradientColoroffset: string | any[], 90 | gradientColors: ColorValue[] 91 | ): ColorListProp[] => { 92 | const minLength: number = Math.min( 93 | gradientColoroffset.length, 94 | gradientColors.length 95 | ); 96 | const colorList: ColorListProp[] = []; 97 | for (let i = 0; i < minLength; i++) { 98 | colorList.push({ 99 | offset: gradientColoroffset[i] || undefined, 100 | color: gradientColors[i] || undefined, 101 | opacity: '1', 102 | }); 103 | } 104 | return colorList; 105 | }; 106 | 107 | export { getGradientFromName, getColorList, getAnglePercentageObject }; 108 | -------------------------------------------------------------------------------- /src/components/SpinnerComponent/SpinnerComponent.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | BallIndicator, 4 | BarIndicator, 5 | DotIndicator, 6 | MaterialIndicator, 7 | PacmanIndicator, 8 | PulseIndicator, 9 | SkypeIndicator, 10 | UIActivityIndicator, 11 | WaveIndicator, 12 | } from 'react-native-indicators'; 13 | import { ActivityIndicator, Platform } from 'react-native'; 14 | import type { ColorValue } from 'react-native'; 15 | import { DEFAULT_COLOR_WHITE, getWaveFactorAndMode } from '../../utils'; 16 | import type { SpinnerComponentProp } from './SpinnerComponentTypes'; 17 | 18 | const SpinnerComponent: React.FC = ({ 19 | height, 20 | size, 21 | spinnerColor, 22 | spinnerType, 23 | indicatorCount, 24 | spinnerOptions, 25 | }: SpinnerComponentProp) => { 26 | const spinnerColors: ColorValue = ( 27 | spinnerColor || DEFAULT_COLOR_WHITE 28 | ).toString(); 29 | 30 | switch (spinnerType?.trim()?.toLowerCase()) { 31 | case 'barindicator': 32 | return ( 33 | 38 | ); 39 | 40 | case 'dotindicator': 41 | return ( 42 | 47 | ); 48 | 49 | case 'materialindicator': 50 | // Note: To overcome https://github.com/n4kz/react-native-indicators/issues/11 and 51 | // https://github.com/n4kz/react-native-indicators/issues/6 ActivityIndicator is used in android 52 | if (Platform.OS === 'android') { 53 | return ; 54 | } 55 | return ; 56 | 57 | case 'pacmanindicator': 58 | return ; 59 | 60 | case 'pulseindicator': 61 | return ; 62 | 63 | case 'skypeindicator': 64 | return ( 65 | 70 | ); 71 | 72 | case 'uiactivityindicator': 73 | return ( 74 | 79 | ); 80 | 81 | case 'waveindicator': 82 | const { waveFactor, waveMode } = getWaveFactorAndMode(spinnerOptions); 83 | return ( 84 | 91 | ); 92 | 93 | default: 94 | return ( 95 | 100 | ); 101 | } 102 | }; 103 | 104 | export default SpinnerComponent; 105 | -------------------------------------------------------------------------------- /example/android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%"=="" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%"=="" set DIRNAME=. 29 | @rem This is normally unused 30 | set APP_BASE_NAME=%~n0 31 | set APP_HOME=%DIRNAME% 32 | 33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 35 | 36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 38 | 39 | @rem Find java.exe 40 | if defined JAVA_HOME goto findJavaFromJavaHome 41 | 42 | set JAVA_EXE=java.exe 43 | %JAVA_EXE% -version >NUL 2>&1 44 | if %ERRORLEVEL% equ 0 goto execute 45 | 46 | echo. 47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 48 | echo. 49 | echo Please set the JAVA_HOME variable in your environment to match the 50 | echo location of your Java installation. 51 | 52 | goto fail 53 | 54 | :findJavaFromJavaHome 55 | set JAVA_HOME=%JAVA_HOME:"=% 56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 57 | 58 | if exist "%JAVA_EXE%" goto execute 59 | 60 | echo. 61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 62 | echo. 63 | echo Please set the JAVA_HOME variable in your environment to match the 64 | echo location of your Java installation. 65 | 66 | goto fail 67 | 68 | :execute 69 | @rem Setup the command line 70 | 71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 72 | 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if %ERRORLEVEL% equ 0 goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | set EXIT_CODE=%ERRORLEVEL% 85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 87 | exit /b %EXIT_CODE% 88 | 89 | :mainEnd 90 | if "%OS%"=="Windows_NT" endlocal 91 | 92 | :omega 93 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | This is a new [**React Native**](https://reactnative.dev) project, bootstrapped using [`@react-native-community/cli`](https://github.com/react-native-community/cli). 2 | 3 | # Getting Started 4 | 5 | >**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. 6 | 7 | ## Step 1: Start the Metro Server 8 | 9 | First, you will need to start **Metro**, the JavaScript _bundler_ that ships _with_ React Native. 10 | 11 | To start Metro, run the following command from the _root_ of your React Native project: 12 | 13 | ```bash 14 | # using npm 15 | npm start 16 | 17 | # OR using Yarn 18 | yarn start 19 | ``` 20 | 21 | ## Step 2: Start your Application 22 | 23 | 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: 24 | 25 | ### For Android 26 | 27 | ```bash 28 | # using npm 29 | npm run android 30 | 31 | # OR using Yarn 32 | yarn android 33 | ``` 34 | 35 | ### For iOS 36 | 37 | ```bash 38 | # using npm 39 | npm run ios 40 | 41 | # OR using Yarn 42 | yarn ios 43 | ``` 44 | 45 | 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. 46 | 47 | This is one way to run your app — you can also run it directly from within Android Studio and Xcode respectively. 48 | 49 | ## Step 3: Modifying your App 50 | 51 | Now that you have successfully run the app, let's modify it. 52 | 53 | 1. Open `App.tsx` in your text editor of choice and edit some lines. 54 | 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! 55 | 56 | For **iOS**: Hit Cmd ⌘ + R in your iOS Simulator to reload the app and see your changes! 57 | 58 | ## Congratulations! :tada: 59 | 60 | You've successfully run and modified your React Native App. :partying_face: 61 | 62 | ### Now what? 63 | 64 | - 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). 65 | - If you're curious to learn more about React Native, check out the [Introduction to React Native](https://reactnative.dev/docs/getting-started). 66 | 67 | # Troubleshooting 68 | 69 | If you can't get this to work, see the [Troubleshooting](https://reactnative.dev/docs/troubleshooting) page. 70 | 71 | # Learn More 72 | 73 | To learn more about React Native, take a look at the following resources: 74 | 75 | - [React Native Website](https://reactnative.dev) - learn more about React Native. 76 | - [Getting Started](https://reactnative.dev/docs/environment-setup) - an **overview** of React Native and how setup your environment. 77 | - [Learn the Basics](https://reactnative.dev/docs/getting-started) - a **guided tour** of the React Native **basics**. 78 | - [Blog](https://reactnative.dev/blog) - read the latest official React Native **Blog** posts. 79 | - [`@facebook/react-native`](https://github.com/facebook/react-native) - the Open Source; GitHub **repository** for React Native. 80 | -------------------------------------------------------------------------------- /example/ios/example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 53 | 55 | 61 | 62 | 63 | 64 | 70 | 72 | 78 | 79 | 80 | 81 | 83 | 84 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /example/android/app/src/debug/java/com/example/ReactNativeFlipper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. 3 | * 4 | *

This source code is licensed under the MIT license found in the LICENSE file in the root 5 | * directory of this source tree. 6 | */ 7 | package com.example; 8 | 9 | import android.content.Context; 10 | import com.facebook.flipper.android.AndroidFlipperClient; 11 | import com.facebook.flipper.android.utils.FlipperUtils; 12 | import com.facebook.flipper.core.FlipperClient; 13 | import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin; 14 | import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin; 15 | import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin; 16 | import com.facebook.flipper.plugins.inspector.DescriptorMapping; 17 | import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin; 18 | import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor; 19 | import com.facebook.flipper.plugins.network.NetworkFlipperPlugin; 20 | import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin; 21 | import com.facebook.react.ReactInstanceEventListener; 22 | import com.facebook.react.ReactInstanceManager; 23 | import com.facebook.react.bridge.ReactContext; 24 | import com.facebook.react.modules.network.NetworkingModule; 25 | import okhttp3.OkHttpClient; 26 | 27 | /** 28 | * Class responsible of loading Flipper inside your React Native application. This is the debug 29 | * flavor of it. Here you can add your own plugins and customize the Flipper setup. 30 | */ 31 | public class ReactNativeFlipper { 32 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { 33 | if (FlipperUtils.shouldEnableFlipper(context)) { 34 | final FlipperClient client = AndroidFlipperClient.getInstance(context); 35 | 36 | client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults())); 37 | client.addPlugin(new DatabasesFlipperPlugin(context)); 38 | client.addPlugin(new SharedPreferencesFlipperPlugin(context)); 39 | client.addPlugin(CrashReporterPlugin.getInstance()); 40 | 41 | NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin(); 42 | NetworkingModule.setCustomClientBuilder( 43 | new NetworkingModule.CustomClientBuilder() { 44 | @Override 45 | public void apply(OkHttpClient.Builder builder) { 46 | builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin)); 47 | } 48 | }); 49 | client.addPlugin(networkFlipperPlugin); 50 | client.start(); 51 | 52 | // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized 53 | // Hence we run if after all native modules have been initialized 54 | ReactContext reactContext = reactInstanceManager.getCurrentReactContext(); 55 | if (reactContext == null) { 56 | reactInstanceManager.addReactInstanceEventListener( 57 | new ReactInstanceEventListener() { 58 | @Override 59 | public void onReactContextInitialized(ReactContext reactContext) { 60 | reactInstanceManager.removeReactInstanceEventListener(this); 61 | reactContext.runOnNativeModulesQueueThread( 62 | new Runnable() { 63 | @Override 64 | public void run() { 65 | client.addPlugin(new FrescoFlipperPlugin()); 66 | } 67 | }); 68 | } 69 | }); 70 | } else { 71 | client.addPlugin(new FrescoFlipperPlugin()); 72 | } 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-spinner-button", 3 | "version": "1.4.3", 4 | "description": "React Native Spinner Button component library", 5 | "author": "Simform Solutions", 6 | "main": "lib/index", 7 | "types": "lib/index.d.ts", 8 | "scripts": { 9 | "prepare": "husky install && yarn build", 10 | "clean": "rm -rf node_modules", 11 | "build": "rm -rf lib && tsc -p .", 12 | "lint": "eslint . --ext .js,.jsx,.ts,.tsx", 13 | "lint:fix": "eslint 'src/**/*.{js,jsx,ts,tsx}' -c .eslintrc --fix ", 14 | "build:local": "yarn build && yarn pack", 15 | "test": "jest", 16 | "example": "yarn --cwd example", 17 | "coverage": "yarn test -u --coverage --watchAll --collectCoverageFrom='src/components/**/*.{ts,tsx}'" 18 | }, 19 | "peerDependencies": { 20 | "react": "*", 21 | "react-native": "*", 22 | "react-native-svg": "*", 23 | "react-native-gradients": "*" 24 | }, 25 | "repository": { 26 | "type": "git", 27 | "url": "git+https://github.com/simformsolutions/react-native-spinner-button.git" 28 | }, 29 | "keywords": [ 30 | "react-native-spinner-button", 31 | "react-native-spinner", 32 | "react-native-button", 33 | "react-native button with spinner", 34 | "react-native button with loader", 35 | "react-native button with activityindicator", 36 | "react-native-loader", 37 | "spinner", 38 | "button", 39 | "loader" 40 | ], 41 | "license": "MIT", 42 | "bugs": { 43 | "url": "https://github.com/simformsolutions/react-native-spinner-button/issues" 44 | }, 45 | "homepage": "https://github.com/simformsolutions/react-native-spinner-button#readme", 46 | "dependencies": { 47 | "react-native-animatable": "^1.3.3", 48 | "react-native-gradients": "^2.1.1", 49 | "react-native-indicators": "^0.17.0", 50 | "react-native-svg": "^14.1.0" 51 | }, 52 | "devDependencies": { 53 | "@babel/core": "^7.8.4", 54 | "@babel/runtime": "^7.8.4", 55 | "@commitlint/cli": "^18.6.1", 56 | "@commitlint/config-conventional": "^18.6.2", 57 | "@react-native-community/eslint-config": "^3.0.1", 58 | "@testing-library/react-native": "^12.4.3", 59 | "@tsconfig/react-native": "^3.0.3", 60 | "@types/jest": "^29.5.12", 61 | "@types/lodash": "^4.14.202", 62 | "@types/react-native": "^0.73.0", 63 | "@types/react-native-indicators": "^0.16.1", 64 | "@types/react-test-renderer": "^18.0.7", 65 | "@typescript-eslint/eslint-plugin": "^5.29.0", 66 | "@typescript-eslint/parser": "^5.29.0", 67 | "babel-jest": "^29.7.0", 68 | "eslint": "^8", 69 | "eslint-plugin-prettier": "^5.1.3", 70 | "eslint-plugin-simple-import-sort": "^12.0.0", 71 | "husky": "^8.0.3", 72 | "jest": "^25.1.0", 73 | "lint-staged": "^15.2.2", 74 | "lodash": "^4.17.21", 75 | "metro-react-native-babel-preset": "^0.59.0", 76 | "prettier": "^3.2.5", 77 | "react": "^18.2.0", 78 | "react-native": "^0.73.4", 79 | "react-test-renderer": "16.13.1", 80 | "typescript": "4.7.4" 81 | }, 82 | "husky": { 83 | "hooks": { 84 | "pre-commit": "lint-staged", 85 | "pre-push": "yarn build && yarn test" 86 | } 87 | }, 88 | "lint-staged": { 89 | "src/**/*.{js,ts,tsx}": [ 90 | "eslint" 91 | ] 92 | }, 93 | "resolutions": { 94 | "@types/react": "*" 95 | }, 96 | "jest": { 97 | "preset": "react-native", 98 | "moduleFileExtensions": [ 99 | "ts", 100 | "tsx", 101 | "js", 102 | "jsx", 103 | "json", 104 | "node" 105 | ], 106 | "setupFilesAfterEnv": [], 107 | "modulePathIgnorePatterns": [] 108 | }, 109 | "eslintIgnore": [ 110 | "node_modules/", 111 | "lib/" 112 | ], 113 | "commitlint": { 114 | "extends": [ 115 | "@commitlint/config-conventional" 116 | ] 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /example/ios/example/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 24 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /src/utils/useAnimatedValues.tsx: -------------------------------------------------------------------------------- 1 | import { useCallback, useEffect, useRef, useState } from 'react'; 2 | import { Animated, Easing, StyleSheet } from 'react-native'; 3 | import type { StyleProp, ViewStyle, LayoutChangeEvent } from 'react-native'; 4 | import { defaulButtonHeight, defaulButtonWidth } from './SpinnerUtils'; 5 | import type { AnimatedStyleProp } from '../components'; 6 | 7 | type useAnimatedValuesProps = { 8 | isLoading: boolean; 9 | style: StyleProp; 10 | animatedDuration: number; 11 | animateWidth?: number; 12 | animateHeight?: number; 13 | animateRadius?: number; 14 | animationType?: string; 15 | }; 16 | 17 | type Size = { 18 | height: number; 19 | width: number; 20 | }; 21 | 22 | type AnimatedStyle = Animated.WithAnimatedValue; 23 | 24 | const useAnimatedValues = ({ 25 | isLoading, 26 | style, 27 | animatedDuration, 28 | animateWidth, 29 | animateHeight, 30 | animateRadius, 31 | animationType 32 | }: useAnimatedValuesProps) => { 33 | const [size, setSize] = useState(null); 34 | const defaultStyle: ViewStyle = StyleSheet.flatten(style); 35 | const margin: number = (defaultStyle.margin || 36 | defaultStyle.marginLeft || 37 | defaultStyle.marginRight || 38 | defaultStyle.marginHorizontal || 39 | 0) as number; 40 | const defaultWidth: number = 41 | ((defaultStyle.width || size?.width || defaulButtonWidth) as number) - 42 | margin * 2; 43 | const defaultRadius: number = (defaultStyle.borderRadius || 0) as number; 44 | const defaultHeight: number = (defaultStyle.height || 45 | size?.height || 46 | defaulButtonHeight) as number; 47 | const animatedHeight: number = 48 | animateHeight || Math.min(defaultWidth, defaultHeight); 49 | const animatedWidth: number = 50 | animateWidth || Math.min(defaultWidth, defaultHeight); 51 | const animatedRadius: number = 52 | animateRadius || Math.min(defaultWidth, defaultHeight) / 2; 53 | const animatedLoadingValue: Animated.Value = useRef( 54 | new Animated.Value(0) 55 | ).current; 56 | const animatedLoadingForChild: Animated.Value = useRef( 57 | new Animated.Value(0) 58 | ).current; 59 | 60 | const handleLayout = useCallback<(event: LayoutChangeEvent) => void>( 61 | (event: LayoutChangeEvent) => { 62 | const { width, height } = event.nativeEvent.layout; 63 | if (size === null || size === undefined) { 64 | setSize({ width, height }); 65 | } 66 | }, 67 | [size] 68 | ); 69 | 70 | useEffect(() => { 71 | Animated.timing(animatedLoadingValue, { 72 | toValue: isLoading ? 1 : 0, 73 | duration: animatedDuration, 74 | easing: Easing.ease, 75 | useNativeDriver: false, 76 | }).start(); 77 | 78 | Animated.timing(animatedLoadingForChild, { 79 | toValue: isLoading ? 1 : 0, 80 | duration: animatedDuration - animatedDuration / 3, 81 | easing: Easing.ease, 82 | useNativeDriver: false, 83 | }).start(); 84 | }, [ 85 | isLoading, 86 | animatedLoadingValue, 87 | animatedLoadingForChild, 88 | animatedDuration, 89 | ]); 90 | 91 | const animatedWidthValue: Animated.AnimatedInterpolation = 92 | animatedLoadingValue.interpolate({ 93 | inputRange: [0, 1], 94 | outputRange: [defaultWidth, animationType === 'ripple-effect' ? defaultWidth : animatedWidth], 95 | }); 96 | 97 | const animatedHeightValue: Animated.AnimatedInterpolation = 98 | animatedLoadingValue.interpolate({ 99 | inputRange: [0, 1], 100 | outputRange: [defaultHeight, animationType === 'ripple-effect' ? defaultHeight : animatedHeight], 101 | }); 102 | 103 | const animatedBorderValue: Animated.AnimatedInterpolation = 104 | animatedLoadingValue.interpolate({ 105 | inputRange: [0, 1], 106 | outputRange: [defaultRadius, animationType === 'ripple-effect' ? defaultRadius : animatedRadius], 107 | }); 108 | 109 | const animatedOpacityHide: Animated.AnimatedInterpolation = 110 | animatedLoadingForChild.interpolate({ 111 | inputRange: [0, 0.9, 1], 112 | outputRange: [1, 0, 0], 113 | }); 114 | 115 | const animatedOpacityShow: Animated.AnimatedInterpolation = 116 | animatedLoadingForChild.interpolate({ 117 | inputRange: [0, 0.9, 1], 118 | outputRange: [0, 0, 1], 119 | }); 120 | 121 | const animatedStyles: AnimatedStyleProp = { 122 | width: animatedWidthValue, 123 | borderRadius: animatedBorderValue, 124 | height: animatedHeightValue, 125 | elevation: isLoading ? 0 : 2, 126 | overflow: 'hidden', 127 | }; 128 | 129 | const animatedChildHideStyle: AnimatedStyle = { 130 | opacity: animatedOpacityHide, 131 | }; 132 | 133 | const animatedChildShowStyle: AnimatedStyle = { 134 | opacity: animatedOpacityShow, 135 | }; 136 | 137 | return { 138 | handleLayout, 139 | animatedStyles, 140 | animatedChildHideStyle, 141 | animatedChildShowStyle, 142 | }; 143 | }; 144 | 145 | export default useAnimatedValues; 146 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.application" 2 | apply plugin: "com.facebook.react" 3 | 4 | /** 5 | * This is the configuration block to customize your React Native Android app. 6 | * By default you don't need to apply any configuration, just uncomment the lines you need. 7 | */ 8 | react { 9 | /* Folders */ 10 | // The root of your project, i.e. where "package.json" lives. Default is '..' 11 | // root = file("../") 12 | // The folder where the react-native NPM package is. Default is ../node_modules/react-native 13 | // reactNativeDir = file("../node_modules/react-native") 14 | // The folder where the react-native Codegen package is. Default is ../node_modules/@react-native/codegen 15 | // codegenDir = file("../node_modules/@react-native/codegen") 16 | // The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js 17 | // cliFile = file("../node_modules/react-native/cli.js") 18 | 19 | /* Variants */ 20 | // The list of variants to that are debuggable. For those we're going to 21 | // skip the bundling of the JS bundle and the assets. By default is just 'debug'. 22 | // If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants. 23 | // debuggableVariants = ["liteDebug", "prodDebug"] 24 | 25 | /* Bundling */ 26 | // A list containing the node command and its flags. Default is just 'node'. 27 | // nodeExecutableAndArgs = ["node"] 28 | // 29 | // The command to run when bundling. By default is 'bundle' 30 | // bundleCommand = "ram-bundle" 31 | // 32 | // The path to the CLI configuration file. Default is empty. 33 | // bundleConfig = file(../rn-cli.config.js) 34 | // 35 | // The name of the generated asset file containing your JS bundle 36 | // bundleAssetName = "MyApplication.android.bundle" 37 | // 38 | // The entry file for bundle generation. Default is 'index.android.js' or 'index.js' 39 | // entryFile = file("../js/MyApplication.android.js") 40 | // 41 | // A list of extra flags to pass to the 'bundle' commands. 42 | // See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle 43 | // extraPackagerArgs = [] 44 | 45 | /* Hermes Commands */ 46 | // The hermes compiler command to run. By default it is 'hermesc' 47 | // hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc" 48 | // 49 | // The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map" 50 | // hermesFlags = ["-O", "-output-source-map"] 51 | } 52 | 53 | /** 54 | * Set this to true to Run Proguard on Release builds to minify the Java bytecode. 55 | */ 56 | def enableProguardInReleaseBuilds = false 57 | 58 | /** 59 | * The preferred build flavor of JavaScriptCore (JSC) 60 | * 61 | * For example, to use the international variant, you can use: 62 | * `def jscFlavor = 'org.webkit:android-jsc-intl:+'` 63 | * 64 | * The international variant includes ICU i18n library and necessary data 65 | * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that 66 | * give correct results when using with locales other than en-US. Note that 67 | * this variant is about 6MiB larger per architecture than default. 68 | */ 69 | def jscFlavor = 'org.webkit:android-jsc:+' 70 | 71 | android { 72 | ndkVersion rootProject.ext.ndkVersion 73 | 74 | compileSdkVersion rootProject.ext.compileSdkVersion 75 | 76 | namespace "com.example" 77 | defaultConfig { 78 | applicationId "com.example" 79 | minSdkVersion rootProject.ext.minSdkVersion 80 | targetSdkVersion rootProject.ext.targetSdkVersion 81 | versionCode 1 82 | versionName "1.0" 83 | } 84 | signingConfigs { 85 | debug { 86 | storeFile file('debug.keystore') 87 | storePassword 'android' 88 | keyAlias 'androiddebugkey' 89 | keyPassword 'android' 90 | } 91 | } 92 | buildTypes { 93 | debug { 94 | signingConfig signingConfigs.debug 95 | } 96 | release { 97 | // Caution! In production, you need to generate your own keystore file. 98 | // see https://reactnative.dev/docs/signed-apk-android. 99 | signingConfig signingConfigs.debug 100 | minifyEnabled enableProguardInReleaseBuilds 101 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 102 | } 103 | } 104 | } 105 | 106 | dependencies { 107 | // The version of react-native is set by the React Native Gradle Plugin 108 | implementation("com.facebook.react:react-android") 109 | 110 | debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") 111 | debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") { 112 | exclude group:'com.squareup.okhttp3', module:'okhttp' 113 | } 114 | 115 | debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") 116 | if (hermesEnabled.toBoolean()) { 117 | implementation("com.facebook.react:hermes-android") 118 | } else { 119 | implementation jscFlavor 120 | } 121 | } 122 | 123 | apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) 124 | -------------------------------------------------------------------------------- /src/components/SpinnerButton/SpinnerButton.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Animated, TouchableOpacity, View } from 'react-native'; 3 | import type { StyleProp, ViewStyle, ColorValue } from 'react-native'; 4 | import { AnimatableView, AnimatedView, ChildrenView } from '../../components'; 5 | import { 6 | DEFAULT_COLOR_WHITE, 7 | getSpinnerStyle, 8 | useAnimatedValues, 9 | useRippleButton 10 | } from '../../utils'; 11 | import type { SpinnerButtonProps } from './SpinnerButtonTypes'; 12 | import { SpinnerButtonStyle } from '../../styles'; 13 | 14 | const AnimatedTouchablesOpacity: Animated.AnimatedComponent< 15 | typeof TouchableOpacity 16 | > = Animated.createAnimatedComponent(TouchableOpacity); 17 | 18 | const SpinnerButton: React.FC = ({ 19 | animationType, 20 | buttonContainer, 21 | buttonStyle, 22 | borderStyle, 23 | spinnerColor = DEFAULT_COLOR_WHITE, 24 | spinnerType = 'BallIndicator', 25 | onPress, 26 | children, 27 | indicatorCount, 28 | size = 16, 29 | spinnerOptions, 30 | gradientName, 31 | gradientType, 32 | gradientColors, 33 | gradientColoroffset, 34 | gradientColorAngle, 35 | gradientRadialRadius, 36 | gradientButtonHeight, 37 | radialRadiusx, 38 | radialRadiusy, 39 | radialRadiusRX, 40 | radialRadiusRY, 41 | rippleColor = 'rgba(255, 255, 255, .25)', 42 | animatedDuration = 300, 43 | customSpinnerComponent, 44 | animateWidth, 45 | animateHeight, 46 | animateRadius, 47 | isLoading = false, 48 | isConnected = true, 49 | disabled = false, 50 | disableStyle, 51 | disableGradientColors, 52 | }: SpinnerButtonProps) => { 53 | const isDisable: boolean = disabled || !isConnected; 54 | const isAnimationType: boolean = 55 | animationType !== null && animationType !== undefined; 56 | const gradientColor: ColorValue[] | undefined = isDisable 57 | ? disableGradientColors || gradientColors 58 | : gradientColors; 59 | const style: StyleProp = [ 60 | SpinnerButtonStyle.defaultButton, 61 | SpinnerButtonStyle.centerAlign, 62 | buttonStyle, 63 | borderStyle, 64 | isDisable && disableStyle, 65 | ]; 66 | const { height } = getSpinnerStyle(style, SpinnerButtonStyle.defaultButton); 67 | const { 68 | handleLayout, 69 | animatedStyles, 70 | animatedChildHideStyle, 71 | animatedChildShowStyle, 72 | } = useAnimatedValues({ 73 | isLoading, 74 | style, 75 | animatedDuration, 76 | animateWidth, 77 | animateHeight, 78 | animateRadius, 79 | animationType 80 | }); 81 | const { handleRipplePress, handleRippleLayout, animatedStyle } = useRippleButton({ 82 | onPress, 83 | animatedDuration, 84 | }); 85 | 86 | return ( 87 | 94 | ]} 97 | onPress={onPress} 98 | disabled={isDisable || isLoading}> 99 | 114 | {isAnimationType && animationType === 'ripple-effect' && ( 115 | 120 | 124 | {children} 125 | 135 | 136 | 137 | )} 138 | {isAnimationType && typeof animationType === 'string' && animationType !== 'ripple-effect' && ( 139 | 152 | )} 153 | {!isAnimationType && ( 154 | 166 | )} 167 | 168 | } 169 | /> 170 | 171 | 172 | ); 173 | }; 174 | 175 | export default SpinnerButton; 176 | -------------------------------------------------------------------------------- /src/components/SpinnerButton/SpinnerButtonTypes.ts: -------------------------------------------------------------------------------- 1 | import type { StyleProp, ViewStyle, ColorValue } from 'react-native'; 2 | import type { SpinnerType } from '..'; 3 | 4 | export type waveModeType = 'fill' | 'outline' | undefined; 5 | export type SpinnerOptionsProp = { 6 | waveFactor?: number; 7 | waveMode?: waveModeType; 8 | }; 9 | 10 | export type GradientType = 'Linear' | 'Radial'; 11 | 12 | export type GradientNames = 13 | | 'Warm Flame' 14 | | 'Night Fade' 15 | | 'Spring Warmth' 16 | | 'Juicy Peach' 17 | | 'Young Passion' 18 | | 'Lady Lips' 19 | | 'Sunny Morning' 20 | | 'Rainy Ashville' 21 | | 'Frozen Dreams' 22 | | 'Winter Neva' 23 | | 'Dusty Grass' 24 | | 'Tempting Azure' 25 | | 'Heavy Rain' 26 | | 'Amy Crisp' 27 | | 'Mean Fruit' 28 | | 'Deep Blue' 29 | | 'Ripe Malinka' 30 | | 'Cloudy Knoxville' 31 | | 'Malibu Beach' 32 | | 'New Life' 33 | | 'True Sunset' 34 | | 'Morpheus Den' 35 | | 'Rare Wind' 36 | | 'Near Moon' 37 | | 'Wild Apple' 38 | | 'Saint Petersburg' 39 | | 'Plum Plate' 40 | | 'Everlasting Sky' 41 | | 'Happy Fisher' 42 | | 'Blessing' 43 | | 'Sharpeye Eagle' 44 | | 'Ladoga Bottom' 45 | | 'Lemon Gate' 46 | | 'Itmeo Branding' 47 | | 'Zeus Miracle' 48 | | 'Old Hat' 49 | | 'Star Wine' 50 | | 'Happy Acid' 51 | | 'Awesome Pine' 52 | | 'New York' 53 | | 'Shy Rainbow' 54 | | 'Mixed Hopes' 55 | | 'Fly High' 56 | | 'Strong Bliss' 57 | | 'Fresh Milk' 58 | | 'Snow Again' 59 | | 'February Ink' 60 | | 'Kind Steel' 61 | | 'Soft Grass' 62 | | 'Grown Early' 63 | | 'Sharp Blues' 64 | | 'Shady Water' 65 | | 'Dirty Beauty' 66 | | 'Great Whale' 67 | | 'Teen Notebook' 68 | | 'Polite Rumors' 69 | | 'Sweet Period' 70 | | 'Wide Matrix' 71 | | 'Soft Cherish' 72 | | 'Red Salvation' 73 | | 'Burning Spring' 74 | | 'Night Party' 75 | | 'Sky Glider' 76 | | 'Heaven Peach' 77 | | 'Purple Division' 78 | | 'Aqua Splash' 79 | | 'Spiky Naga' 80 | | 'Love Kiss' 81 | | 'Clean Mirror' 82 | | 'Premium Dark' 83 | | 'Cold Evening' 84 | | 'Cochiti Lake' 85 | | 'Summer Games' 86 | | 'Passionate Bed' 87 | | 'Mountain Rock' 88 | | 'Desert Hump' 89 | | 'Jungle Day' 90 | | 'Phoenix Start' 91 | | 'October Silence' 92 | | 'Faraway River' 93 | | 'Alchemist Lab' 94 | | 'Over Sun' 95 | | 'Premium White' 96 | | 'Mars Party' 97 | | 'Eternal Constance' 98 | | 'Japan Blush' 99 | | 'Smiling Rain' 100 | | 'Cloudy Apple' 101 | | 'Big Mango' 102 | | 'Healthy Water' 103 | | 'Amour Amour' 104 | | 'Risky Concrete' 105 | | 'Strong Stick' 106 | | 'Vicious Stance' 107 | | 'Palo Alto' 108 | | 'Happy Memories' 109 | | 'Midnight Bloom' 110 | | 'Crystalline' 111 | | 'Party Bliss' 112 | | 'Confident Cloud' 113 | | 'Le Cocktail' 114 | | 'River City' 115 | | 'Frozen Berry' 116 | | 'Child Care' 117 | | 'Flying Lemon' 118 | | 'New Retrowave' 119 | | 'Hidden Jaguar' 120 | | 'Above The Sky' 121 | | 'Nega' 122 | | 'Dense Water' 123 | | 'Seashore' 124 | | 'Marble Wall' 125 | | 'Cheerful Caramel' 126 | | 'Night Sky' 127 | | 'Magic Lake' 128 | | 'Young Grass' 129 | | 'Colorful Peach' 130 | | 'Gentle Care' 131 | | 'Plum Bath' 132 | | 'Happy Unicorn' 133 | | 'African Field' 134 | | 'Solid Stone' 135 | | 'Orange Juice' 136 | | 'Glass Water' 137 | | 'North Miracle' 138 | | 'Fruit Blend' 139 | | 'Millennium Pine' 140 | | 'High Flight' 141 | | 'Mole Hall' 142 | | 'Space Shift' 143 | | 'Forest Inei' 144 | | 'Royal Garden' 145 | | 'Rich Metal' 146 | | 'Juicy Cake' 147 | | 'Smart Indigo' 148 | | 'Sand Strike' 149 | | 'Norse Beauty' 150 | | 'Aqua Guidance' 151 | | 'Sun Veggie' 152 | | 'Sea Lord' 153 | | 'Black Sea' 154 | | 'Grass Shampoo' 155 | | 'Landing Aircraft' 156 | | 'Witch Dance' 157 | | 'Sleepless Night' 158 | | 'Angel Care' 159 | | 'Crystal River' 160 | | 'Soft Lipstick' 161 | | 'Salt Mountain' 162 | | 'Perfect White' 163 | | 'Fresh Oasis' 164 | | 'Strict November' 165 | | 'Morning Salad' 166 | | 'Deep Relief' 167 | | 'Sea Strike' 168 | | 'Night Call' 169 | | 'Supreme Sky' 170 | | 'Light Blue' 171 | | 'Mind Crawl' 172 | | 'Lily Meadow' 173 | | 'Sugar Lollipop' 174 | | 'Sweet Dessert' 175 | | 'Magic Ray' 176 | | 'Teen Party' 177 | | 'Frozen Heat' 178 | | 'Gagarin View' 179 | | 'Fabled Sunset' 180 | | 'Perfect Blue'; 181 | 182 | export interface CommonOptionalProps { 183 | animationType?: string; 184 | buttonContainer?: StyleProp; 185 | buttonStyle?: StyleProp; 186 | borderStyle?: StyleProp; 187 | spinnerColor?: ColorValue; 188 | spinnerType?: SpinnerType; 189 | indicatorCount?: number; 190 | size?: number; 191 | spinnerOptions?: SpinnerOptionsProp; 192 | gradientColors?: ColorValue[]; 193 | gradientColoroffset?: string[]; 194 | gradientColorAngle?: number; 195 | animatedDuration?: number; 196 | customSpinnerComponent?: JSX.Element; 197 | animateWidth?: number; 198 | animateHeight?: number; 199 | animateRadius?: number; 200 | disabled?: boolean; 201 | isLoading?: boolean; 202 | isConnected?: boolean; 203 | disableStyle?: StyleProp; 204 | disableGradientColors?: ColorValue[]; 205 | gradientName?: GradientNames; 206 | radialRadiusx?: string | number; 207 | radialRadiusy?: string | number; 208 | radialRadiusRX?: string | number; 209 | radialRadiusRY?: string | number; 210 | rippleColor?: string; 211 | gradientRadialRadius?: number; 212 | gradientButtonHeight?: number; 213 | } 214 | 215 | export interface SpinnerButtonBaseProps extends CommonOptionalProps { 216 | onPress: () => void; 217 | children: JSX.Element; 218 | } 219 | 220 | export interface LinearGradientBaseProps extends CommonOptionalProps { 221 | gradientType: 'Linear'; 222 | gradientRadialRadius: number; 223 | gradientButtonHeight: number; 224 | } 225 | 226 | export interface RadialGradientBaseProps extends CommonOptionalProps { 227 | gradientType: 'Radial'; 228 | radialRadiusx: string | number; 229 | radialRadiusy: string | number; 230 | radialRadiusRX: string | number; 231 | radialRadiusRY: string | number; 232 | gradientRadialRadius: number; 233 | gradientButtonHeight: number; 234 | } 235 | 236 | export interface BasicSpinnerButtonBaseProps extends CommonOptionalProps { 237 | gradientType?: never; 238 | } 239 | 240 | type BasicSpinnerButtonProps = SpinnerButtonBaseProps & 241 | BasicSpinnerButtonBaseProps; 242 | 243 | type LinearGradientProps = SpinnerButtonBaseProps & LinearGradientBaseProps; 244 | 245 | type RadialGradientProps = SpinnerButtonBaseProps & RadialGradientBaseProps; 246 | 247 | export type SpinnerButtonProps = 248 | | BasicSpinnerButtonProps 249 | | LinearGradientProps 250 | | RadialGradientProps; 251 | -------------------------------------------------------------------------------- /example/android/gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | # 21 | # Gradle start up script for POSIX generated by Gradle. 22 | # 23 | # Important for running: 24 | # 25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 26 | # noncompliant, but you have some other compliant shell such as ksh or 27 | # bash, then to run this script, type that shell name before the whole 28 | # command line, like: 29 | # 30 | # ksh Gradle 31 | # 32 | # Busybox and similar reduced shells will NOT work, because this script 33 | # requires all of these POSIX shell features: 34 | # * functions; 35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 37 | # * compound commands having a testable exit status, especially «case»; 38 | # * various built-in commands including «command», «set», and «ulimit». 39 | # 40 | # Important for patching: 41 | # 42 | # (2) This script targets any POSIX shell, so it avoids extensions provided 43 | # by Bash, Ksh, etc; in particular arrays are avoided. 44 | # 45 | # The "traditional" practice of packing multiple parameters into a 46 | # space-separated string is a well documented source of bugs and security 47 | # problems, so this is (mostly) avoided, by progressively accumulating 48 | # options in "$@", and eventually passing that to Java. 49 | # 50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 52 | # see the in-line comments for details. 53 | # 54 | # There are tweaks for specific operating systems such as AIX, CygWin, 55 | # Darwin, MinGW, and NonStop. 56 | # 57 | # (3) This script is generated from the Groovy template 58 | # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 59 | # within the Gradle project. 60 | # 61 | # You can find Gradle at https://github.com/gradle/gradle/. 62 | # 63 | ############################################################################## 64 | 65 | # Attempt to set APP_HOME 66 | 67 | # Resolve links: $0 may be a link 68 | app_path=$0 69 | 70 | # Need this for daisy-chained symlinks. 71 | while 72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 73 | [ -h "$app_path" ] 74 | do 75 | ls=$( ls -ld "$app_path" ) 76 | link=${ls#*' -> '} 77 | case $link in #( 78 | /*) app_path=$link ;; #( 79 | *) app_path=$APP_HOME$link ;; 80 | esac 81 | done 82 | 83 | # This is normally unused 84 | # shellcheck disable=SC2034 85 | APP_BASE_NAME=${0##*/} 86 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit 87 | 88 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 89 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 90 | 91 | # Use the maximum available, or set MAX_FD != -1 to use that value. 92 | MAX_FD=maximum 93 | 94 | warn () { 95 | echo "$*" 96 | } >&2 97 | 98 | die () { 99 | echo 100 | echo "$*" 101 | echo 102 | exit 1 103 | } >&2 104 | 105 | # OS specific support (must be 'true' or 'false'). 106 | cygwin=false 107 | msys=false 108 | darwin=false 109 | nonstop=false 110 | case "$( uname )" in #( 111 | CYGWIN* ) cygwin=true ;; #( 112 | Darwin* ) darwin=true ;; #( 113 | MSYS* | MINGW* ) msys=true ;; #( 114 | NONSTOP* ) nonstop=true ;; 115 | esac 116 | 117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 118 | 119 | 120 | # Determine the Java command to use to start the JVM. 121 | if [ -n "$JAVA_HOME" ] ; then 122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 123 | # IBM's JDK on AIX uses strange locations for the executables 124 | JAVACMD=$JAVA_HOME/jre/sh/java 125 | else 126 | JAVACMD=$JAVA_HOME/bin/java 127 | fi 128 | if [ ! -x "$JAVACMD" ] ; then 129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 130 | 131 | Please set the JAVA_HOME variable in your environment to match the 132 | location of your Java installation." 133 | fi 134 | else 135 | JAVACMD=java 136 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 137 | 138 | Please set the JAVA_HOME variable in your environment to match the 139 | location of your Java installation." 140 | fi 141 | 142 | # Increase the maximum file descriptors if we can. 143 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 144 | case $MAX_FD in #( 145 | max*) 146 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. 147 | # shellcheck disable=SC3045 148 | MAX_FD=$( ulimit -H -n ) || 149 | warn "Could not query maximum file descriptor limit" 150 | esac 151 | case $MAX_FD in #( 152 | '' | soft) :;; #( 153 | *) 154 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. 155 | # shellcheck disable=SC3045 156 | ulimit -n "$MAX_FD" || 157 | warn "Could not set maximum file descriptor limit to $MAX_FD" 158 | esac 159 | fi 160 | 161 | # Collect all arguments for the java command, stacking in reverse order: 162 | # * args from the command line 163 | # * the main class name 164 | # * -classpath 165 | # * -D...appname settings 166 | # * --module-path (only if needed) 167 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 168 | 169 | # For Cygwin or MSYS, switch paths to Windows format before running java 170 | if "$cygwin" || "$msys" ; then 171 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 172 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 173 | 174 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 175 | 176 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 177 | for arg do 178 | if 179 | case $arg in #( 180 | -*) false ;; # don't mess with options #( 181 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 182 | [ -e "$t" ] ;; #( 183 | *) false ;; 184 | esac 185 | then 186 | arg=$( cygpath --path --ignore --mixed "$arg" ) 187 | fi 188 | # Roll the args list around exactly as many times as the number of 189 | # args, so each arg winds up back in the position where it started, but 190 | # possibly modified. 191 | # 192 | # NB: a `for` loop captures its iteration list before it begins, so 193 | # changing the positional parameters here affects neither the number of 194 | # iterations, nor the values presented in `arg`. 195 | shift # remove old arg 196 | set -- "$@" "$arg" # push replacement arg 197 | done 198 | fi 199 | 200 | # Collect all arguments for the java command; 201 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of 202 | # shell script including quotes and variable substitutions, so put them in 203 | # double quotes to make sure that they get re-expanded; and 204 | # * put everything else in single quotes, so that it's not re-expanded. 205 | 206 | set -- \ 207 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 208 | -classpath "$CLASSPATH" \ 209 | org.gradle.wrapper.GradleWrapperMain \ 210 | "$@" 211 | 212 | # Stop when "xargs" is not available. 213 | if ! command -v xargs >/dev/null 2>&1 214 | then 215 | die "xargs is not available" 216 | fi 217 | 218 | # Use "xargs" to parse quoted args. 219 | # 220 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 221 | # 222 | # In Bash we could simply go: 223 | # 224 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 225 | # set -- "${ARGS[@]}" "$@" 226 | # 227 | # but POSIX shell has neither arrays nor command substitution, so instead we 228 | # post-process each arg (as a line of input to sed) to backslash-escape any 229 | # character that might be a shell metacharacter, then use eval to reverse 230 | # that process (while maintaining the separation between arguments), and wrap 231 | # the whole thing up as a single "set" statement. 232 | # 233 | # This will of course break if any of these variables contains a newline or 234 | # an unmatched quote. 235 | # 236 | 237 | eval "set -- $( 238 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 239 | xargs -n1 | 240 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 241 | tr '\n' ' ' 242 | )" '"$@"' 243 | 244 | exec "$JAVACMD" "$@" 245 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Tree-Selection](./assets/react-native-spinner-button.png) 2 | 3 | # react-native-spinner-button [![npm version](https://badge.fury.io/js/react-native-spinner-button.svg)](https://badge.fury.io/js/react-native-spinner-button) [![Android](https://img.shields.io/badge/Platform-Android-green?logo=android)](https://www.android.com) [![iOS](https://img.shields.io/badge/Platform-iOS-green?logo=apple)](https://developer.apple.com/ios) [![MIT](https://img.shields.io/badge/License-MIT-green)](https://opensource.org/licenses/MIT) 4 | React Native Spinner Button component library provides dynamic spinner buttons and ripple effects, enriching the user experience with smooth animations and intuitive feedback 5 | 6 | Library is compatible with both Android and iOS platforms, offering a versatile solution to elevate your app's user interface with ease. 7 | 8 | ## 🎬 Preview 9 | 10 | ![Example of react-native-spinner-button](./assets/example.gif) 11 | 12 | ## Quick Access 13 | 14 | [Installation](#installation) | [Usage and Examples](#usage) | [Properties](#properties) | [Example Code](#example) | [License](#license) 15 | 16 | ## Getting Started 17 | 18 | Here's how to get started with react-native-spinner-button in your React Native project: 19 | 20 | ### Installation 21 | 22 | #### 1. Install the package 23 | 24 | ```sh 25 | npm install react-native-spinner-button react-native-gradients react-native-svg 26 | ``` 27 | 28 | Using `Yarn`: 29 | 30 | ```sh 31 | yarn add react-native-spinner-button react-native-gradients react-native-svg 32 | ``` 33 | 34 | ##### 2. Install cocoapods in the ios project 35 | 36 | ```bash 37 | cd ios && pod install 38 | ``` 39 | 40 | 41 | ##### Know more about [react-native-gradients](https://www.npmjs.com/package/react-native-gradients) and [react-native-svg](https://www.npmjs.com/package/react-native-svg) 42 | 43 | 44 | ## Usage 45 | 46 | ```jsx 47 | import React, {useState, useCallback} from 'react'; 48 | import {StyleSheet, Text, View} from 'react-native'; 49 | import SpinnerButton from 'react-native-spinner-button'; 50 | 51 | const App: React.FC = () => { 52 | const [isLoading, setLoading] = useState(false); 53 | 54 | const handleButtonPress = useCallback<() => void>(() => { 55 | setLoading(true); 56 | setTimeout(() => { 57 | setLoading(false); 58 | }, 3000); 59 | }, []); 60 | 61 | return ( 62 | 63 | {/* Your button component */} 64 | { 68 | handleButtonPress(); 69 | }} 70 | indicatorCount={10} 71 | > 72 | Default Or Ball SpinnerButton 73 | 74 | 75 | ); 76 | }; 77 | 78 | export default App; 79 | 80 | const styles = StyleSheet.create({ 81 | screen: { 82 | flex: 1, 83 | justifyContent: 'center', 84 | alignItems: 'center', 85 | }, 86 | buttonStyle: { 87 | borderRadius: 10, 88 | margin: 10, 89 | backgroundColor: '#893346', 90 | }, 91 | buttonText: { 92 | fontSize: 20, 93 | textAlign: 'center', 94 | color: 'white', 95 | }, 96 | }); 97 | ``` 98 | 99 | 100 | Example of Ripple Effect Button 101 | 102 | ```jsx 103 | import React from 'react'; 104 | import {StyleSheet, Text, View} from 'react-native'; 105 | import SpinnerButton from 'react-native-spinner-button'; 106 | 107 | const App: React.FC = () => { 108 | const buttonPress: () => void = () => { 109 | console.log('Button Clicked'); 110 | }; 111 | 112 | return ( 113 | 114 | 119 | RippleButton 120 | 121 | 122 | ); 123 | }; 124 | 125 | const styles = StyleSheet.create({ 126 | screen: { 127 | flex: 1, 128 | justifyContent: 'center', 129 | }, 130 | btnStyle: { 131 | margin: 10, 132 | backgroundColor: '#893346', 133 | }, 134 | textStyle: { 135 | fontSize: 20, 136 | textAlign: 'center', 137 | color: 'white', 138 | }, 139 | }); 140 | 141 | export default App; 142 | ``` 143 | 144 | 145 | #### 🎬 Preview 146 | 147 | | Spinner Button | Ripple Button | 148 | | :-------: | :-----:| 149 | | ![alt Default](./assets/exampleDemo1.gif) | ![alt Modal](./assets/exampleDemo2.gif) | 150 | 151 | 152 | ## Properties 153 | 154 | Props for the spinner button 155 | 156 | | Props | Default | Type | Description | 157 | | :-------------------- | :-----: | :---------------------: | :--------------------------------------------------------------------------------------------------- | 158 | | **onPress** | - | function | The function to execute upon tapping the button | 159 | | animationType | null or undefined | string | Type of animation for the button and spinner, For more details about properties, refer [react-native-animatable](https://www.npmjs.com/package/react-native-animatable) and also support "ripple-effect" | 160 | | buttonStyle | {height: 50} | array or object | Button styling | 161 | | borderStyle | - | array or object | It's a stylesheet object supporting all basic border properties like width, radius, color, and style (solid, dotted, and dashed), etc | 162 | | spinnerColor | white | string | The color of the spinner | 163 | | spinnerType | BallIndicator | string | Type of the spinner: BallIndicator, BarIndicator, DotIndicator, MaterialIndicator, PacmanIndicator, PulseIndicator, SkypeIndicator, UIActivityIndicator, WaveIndicator. | 164 | | isLoading | false | boolean | The flag to render a button or a spinner. false will render a button, and true will render a spinner | 165 | | indicatorCount | 8 | number | The count property of react-native-indicators | 166 | | size | 16 | number | The size of the dot in DotIndicator | 167 | | spinnerOptions | - | object | An object of waveMode for WaveIndicator. For more details about these properties, refer [react-native-indicators](https://github.com/n4kz/react-native-indicators) | 168 | | gradientType | - | string | Gradients allow you to display more than one color with a smooth transition between the colors (think Instagram logo). Currently, we support two types of gradients: linear and radial | 169 | | gradientColors | - | array | Colors can be passed in different formats such as name, RGBA, hex, etc. The colors should be ordered in the way we want them to be displayed. For example, colors={[ "purple", "white" ]}, the gradient will transition from purple to white | 170 | | gradientColoroffset | - | array | An array of strings that defines where each color will stop in the gradient. These values are passed as a percentage of the entire gradient from 0% to 100% and must correspond to the colors passed in length and position. For example, with colors={[“red”, “yellow”, “green”]}, then we’ll have locations={['0%', '50%', '80%']}, with the first color (red) covering '0%' – '50%', the second (yellow) going from '50%' – '80%', and the third (green) from '80%' – '100%' | 171 | | gradientColorAngle | - | number | The gradient line's angle of direction. A value of 0deg is equivalent to the top; increasing values rotate clockwise from there. The angle range is from 0 to 360 degrees [More detail to read](https://www.quirksmode.org/css/images/angles.html) | 172 | | gradientRadialRadius | - | number | This property is used for radial type gradients to set the radius of the radial gradient | 173 | | gradientButtonHeight | - | number | The size of the gradient component | 174 | | radialRadiusx | - | string or number | The x-coordinate of the center of the radial gradient 175 | | radialRadiusy | - | string or number | The y-coordinate of the center of the radial gradient | 176 | | radialRadiusRX | - | string or number | The horizontal radius of the radial gradient defining the ellipse | 177 | | radialRadiusRY | - | string or number | The vertical radius of the radial gradient defining the ellipse | 178 | | animatedDuration | 300 | number | This property is used to define the duration of the animation, indicating how long it will take to execute the animation | 179 | | customSpinnerComponent | - | node | This prop allows you to add your own custom spinner component | 180 | | animateWidth | - | number | This prop is used to set the component width when the progress/loading starts. If you do not set this prop, it will identify the width and height which are minimum and then use that value | 181 | | animateHeight | - | number | This prop is used to set the component height when the progress/loading starts. If you do not set this prop, it will identify the width and height which are minimum and then use that value | 182 | | animateRadius | - | number | This prop is used to set the component radius when the progress/loading starts. If you do not set this prop, it will create a circle shape by default | 183 | | isConnected | true | boolean | The flag is used to identify the network connection, and based on the flag, the user iteration is set. false will render the button in disabled mode, and true will render the button in normal mode | 184 | | disabled | false | boolean | The flag to identify button enable/disable. true will render the button in disabled mode, and false will render the button in normal mode | 185 | | disableStyle | - | array or object | It's a stylesheet object. This style applies when identifying the button as disabled or if network connection is not available | 186 | | gradientName | - | string | These properties are used whenever you want to use a gradient but do not pass the gradientColors, gradientColorOffset, and gradientColorAngle properties | 187 | | disableGradientColors | - | array | Colors can be passed in different formats such as names, RGBA, hex, etc. The colors should be ordered in the way we want them to be displayed. For example, with colors={[ "purple", "white" ]}, the gradient will transition from purple to white | 188 | | rippleColor | rgba(255, 255, 255, .25) | string | Color of the ripple animation effect 189 | 190 | ## Example 191 | A full working example project is here [Example](./example/App/App.tsx) 192 | 193 | ```sh 194 | yarn 195 | yarn example ios // For ios 196 | yarn example android // For Android 197 | ``` 198 | 199 | 200 | ## Find this library useful? ❤️ 201 | 202 | Support it by joining [stargazers](https://github.com/SimformSolutionsPvtLtd/react-native-spinner-button/stargazers) for this repository.⭐ 203 | 204 | ## Bugs / Feature requests / Feedbacks 205 | 206 | For bugs, feature requests, and discussion please use [GitHub Issues](https://github.com/SimformSolutionsPvtLtd/react-native-spinner-button/issues/new?labels=bug&late=BUG_REPORT.md&title=%5BBUG%5D%3A), [GitHub New Feature](https://github.com/SimformSolutionsPvtLtd/react-native-spinner-button/issues/new?labels=enhancement&late=FEATURE_REQUEST.md&title=%5BFEATURE%5D%3A), [GitHub Feedback](https://github.com/SimformSolutionsPvtLtd/react-native-spinner-button/issues/new?labels=enhancement&late=FEATURE_REQUEST.md&title=%5BFEEDBACK%5D%3A) 207 | 208 | 209 | ## 🤝 How to Contribute 210 | 211 | We'd love to have you improve this library or fix a problem 💪 212 | Check out our [Contributing Guide](CONTRIBUTING.md) for ideas on contributing. 213 | 214 | ## Awesome Mobile Libraries 215 | 216 | - Check out our other [available awesome mobile libraries](https://github.com/SimformSolutionsPvtLtd/Awesome-Mobile-Libraries) 217 | 218 | ## License 219 | 220 | - [MIT License](./LICENSE) 221 | -------------------------------------------------------------------------------- /src/utils/GradientData.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "name":"Warm Flame", "angle":-45, "colors": ["#ff9a9e", "#fad0c4", "#fad0c4"], "offset": ["0%", "99%", "100%"] }, 3 | { "name":"Night Fade", "angle":-90, "colors": ["#a18cd1", "#fbc2eb"], "offset": ["0%", "100%"] }, 4 | { "name":"Spring Warmth", "angle":-90, "colors": ["#fad0c4", "#fad0c4", "#ffd1ff"], "offset": ["0%", "1%", "100%"] }, 5 | { "name":"Juicy Peach", "angle":0, "colors": ["#ffecd2", "#fcb69f"], "offset": ["0%", "100%"] }, 6 | { "name":"Young Passion", "angle":0, "colors": ["#ff8177", "#ff867a", "#ff8c7f", "#f99185", "#cf556c", "#b12a5b"], "offset": ["0%", "0%", "21%", "52%", "78%", "100%"] }, 7 | { "name":"Lady Lips", "angle":-90, "colors": ["#ff9a9e", "#fecfef", "#fecfef"], "offset": ["0%", "99%", "100%"] }, 8 | { "name":"Sunny Morning", "angle":30, "colors": ["#f6d365", "#fda085"], "offset": ["0%", "100%"] }, 9 | { "name":"Rainy Ashville", "angle":-90, "colors": ["#fbc2eb", "#a6c1ee"], "offset": ["0%", "100%"] }, 10 | { "name":"Frozen Dreams", "angle":-90, "colors": ["#fdcbf1", "#fdcbf1", "#e6dee9"], "offset": ["0%", "1%", "100%"] }, 11 | { "name":"Winter Neva", "angle":30, "colors": ["#a1c4fd", "#c2e9fb"], "offset": ["0%", "100%"] }, 12 | { "name":"Dusty Grass", "angle":30, "colors": ["#d4fc79", "#96e6a1"], "offset": ["0%", "100%"] }, 13 | { "name":"Tempting Azure", "angle":30, "colors": ["#84fab0", "#8fd3f4"], "offset": ["0%", "100%"] }, 14 | { "name":"Heavy Rain", "angle":-90, "colors": ["#cfd9df", "#e2ebf0"], "offset": ["0%", "100%"] }, 15 | { "name":"Amy Crisp", "angle":30, "colors": ["#a6c0fe", "#f68084"], "offset": ["0%", "100%"] }, 16 | { "name":"Mean Fruit", "angle":30, "colors": ["#fccb90", "#d57eeb"], "offset": ["0%", "100%"] }, 17 | { "name":"Deep Blue", "angle":0, "colors": ["#6a11cb", "#2575fc"], "offset": ["0%", "100%"] }, 18 | { "name":"Ripe Malinka", "angle":30, "colors": ["#f093fb", "#f5576c"], "offset": ["0%", "100%"] }, 19 | { "name":"Cloudy Knoxville", "angle":30, "colors": ["#fdfbfb", "#ebedee"], "offset": ["0%", "100%"] }, 20 | { "name":"Malibu Beach", "angle":0, "colors": ["#4facfe", "#00f2fe"], "offset": ["0%", "100%"] }, 21 | { "name":"New Life", "angle":0, "colors": ["#43e97b", "#38f9d7"], "offset": ["0%", "100%"] }, 22 | { "name":"True Sunset", "angle":0, "colors": ["#fa709a", "#fee140"], "offset": ["0%", "100%"] }, 23 | { "name":"Morpheus Den", "angle":-90, "colors": ["#30cfd0", "#330867"], "offset": ["0%", "100%"] }, 24 | { "name":"Rare Wind", "angle":-90, "colors": ["#a8edea", "#fed6e3"], "offset": ["0%", "100%"] }, 25 | { "name":"Near Moon", "angle":-90, "colors": ["#5ee7df", "#b490ca"], "offset": ["0%", "100%"] }, 26 | { "name":"Wild Apple", "angle":-90, "colors": ["#d299c2", "#fef9d7"], "offset": ["0%", "100%"] }, 27 | { "name":"Saint Petersburg", "angle":45, "colors": ["#f5f7fa", "#c3cfe2"], "offset": ["0%", "100%"] }, 28 | { "name":"Plum Plate", "angle":45, "colors": ["#667eea", "#764ba2"], "offset": ["0%", "100%"] }, 29 | { "name":"Everlasting Sky", "angle":45, "colors": ["#fdfcfb", "#e2d1c3"], "offset": ["0%", "100%"] }, 30 | { "name":"Happy Fisher", "angle":30, "colors": ["#89f7fe", "#66a6ff"], "offset": ["0%", "100%"] }, 31 | { "name":"Blessing", "angle":-90, "colors": ["#fddb92", "#d1fdff"], "offset": ["0%", "100%"] }, 32 | { "name":"Sharpeye Eagle", "angle":-90, "colors": ["#9890e3", "#b1f4cf"], "offset": ["0%", "100%"] }, 33 | { "name":"Ladoga Bottom", "angle":-90, "colors": ["#ebc0fd", "#d9ded8"], "offset": ["0%", "100%"] }, 34 | { "name":"Lemon Gate", "angle":-90, "colors": ["#96fbc4", "#f9f586"], "offset": ["0%", "100%"] }, 35 | { "name":"Itmeo Branding", "angle":90, "colors": ["#2af598", "#009efd"], "offset": ["0%", "100%"] }, 36 | { "name":"Zeus Miracle", "angle":-90, "colors": ["#cd9cf2", "#f6f3ff"], "offset": ["0%", "100%"] }, 37 | { "name":"Old Hat", "angle":0, "colors": ["#e4afcb", "#b8cbb8", "#b8cbb8", "#e2c58b", "#c2ce9c", "#7edbdc"], "offset": ["0%", "0%", "0%", "30%", "64%", "100%"] }, 38 | { "name":"Star Wine", "angle":0, "colors": ["#b8cbb8", "#b8cbb8", "#b465da", "#cf6cc9", "#ee609c", "#ee609c"], "offset": ["0%", "0%", "0%", "33%", "66%", "100%"] }, 39 | { "name":"Happy Acid", "angle":-90, "colors": ["#37ecba", "#72afd3"], "offset": ["0%", "100%"] }, 40 | { "name":"Awesome Pine", "angle":-90, "colors": ["#ebbba7", "#cfc7f8"], "offset": ["0%", "100%"] }, 41 | { "name":"New York", "angle":-90, "colors": ["#fff1eb", "#ace0f9"], "offset": ["0%", "100%"] }, 42 | { "name":"Shy Rainbow", "angle":0, "colors": ["#eea2a2", "#bbc1bf", "#57c6e1", "#b49fda", "#7ac5d8"], "offset": ["0%", "19%", "42%", "79%", "100%"] }, 43 | { "name":"Mixed Hopes", "angle":-90, "colors": ["#c471f5", "#fa71cd"], "offset": ["0%", "100%"] }, 44 | { "name":"Fly High", "angle":-90, "colors": ["#48c6ef", "#6f86d6"], "offset": ["0%", "100%"] }, 45 | { "name":"Strong Bliss", "angle":0, "colors": ["#f78ca0", "#f9748f", "#fd868c", "#fe9a8b"], "offset": ["0%", "19%", "60%", "100%"] }, 46 | { "name":"Fresh Milk", "angle":-90, "colors": ["#feada6", "#f5efef"], "offset": ["0%", "100%"] }, 47 | { "name":"Snow Again", "angle":-90, "colors": ["#e6e9f0", "#eef1f5"], "offset": ["0%", "100%"] }, 48 | { "name":"February Ink", "angle":-90, "colors": ["#accbee", "#e7f0fd"], "offset": ["0%", "100%"] }, 49 | { "name":"Kind Steel", "angle":-110, "colors": ["#e9defa", "#fbfcdb"], "offset": ["0%", "100%"] }, 50 | { "name":"Soft Grass", "angle":-90, "colors": ["#c1dfc4", "#deecdd"], "offset": ["0%", "100%"] }, 51 | { "name":"Grown Early", "angle":-90, "colors": ["#0ba360", "#3cba92"], "offset": ["0%", "100%"] }, 52 | { "name":"Sharp Blues", "angle":-90, "colors": ["#00c6fb", "#005bea"], "offset": ["0%", "100%"] }, 53 | { "name":"Shady Water", "angle":0, "colors": ["#74ebd5", "#9face6"], "offset": ["0%", "100%"] }, 54 | { "name":"Dirty Beauty", "angle":-90, "colors": ["#6a85b6", "#bac8e0"], "offset": ["0%", "100%"] }, 55 | { "name":"Great Whale", "angle":-90, "colors": ["#a3bded", "#6991c7"], "offset": ["0%", "100%"] }, 56 | { "name":"Teen Notebook", "angle":-90, "colors": ["#9795f0", "#fbc8d4"], "offset": ["0%", "100%"] }, 57 | { "name":"Polite Rumors", "angle":-90, "colors": ["#a7a6cb", "#8989ba", "#8989ba"], "offset": ["0%", "52%", "100%"] }, 58 | { "name":"Sweet Period", "angle":-90, "colors": ["#3f51b1", "#5a55ae", "#7b5fac", "#8f6aae", "#a86aa4", "#cc6b8e", "#f18271", "#f3a469", "#f7c978"], "offset": ["0%", "13%", "25%", "38%", "50%", "62%", "75%", "87%", "100%"] }, 59 | { "name":"Wide Matrix", "angle":-90, "colors": ["#fcc5e4", "#fda34b", "#ff7882", "#c8699e", "#7046aa", "#0c1db8", "#020f75"], "offset": ["0%", "15%", "35%", "52%", "71%", "87%", "100%"] }, 60 | { "name":"Soft Cherish", "angle":-90, "colors": ["#dbdcd7", "#dddcd7", "#e2c9cc", "#e7627d", "#b8235a", "#801357", "#3d1635", "#1c1a27"], "offset": ["0%", "24%", "30%", "46%", "58%", "71%", "84%", "100%"] }, 61 | { "name":"Red Salvation", "angle":-90, "colors": ["#f43b47", "#453a94"], "offset": ["0%", "100%"] }, 62 | { "name":"Burning Spring", "angle":-90, "colors": ["#4fb576", "#44c489", "#28a9ae", "#28a2b7", "#4c7788", "#6c4f63", "#432c39"], "offset": ["0%", "30%", "46%", "58%", "71%", "86%", "100%"] }, 63 | { "name":"Night Party", "angle":-90, "colors": ["#0250c5", "#d43f8d"], "offset": ["0%", "100%"] }, 64 | { "name":"Sky Glider", "angle":-90, "colors": ["#88d3ce", "#6e45e2"], "offset": ["0%", "100%"] }, 65 | { "name":"Heaven Peach", "angle":-90, "colors": ["#d9afd9", "#97d9e1"], "offset": ["0%", "100%"] }, 66 | { "name":"Purple Division", "angle":-90, "colors": ["#7028e4", "#e5b2ca"], "offset": ["0%", "100%"] }, 67 | { "name":"Aqua Splash", "angle":-75, "colors": ["#13547a", "#80d0c7"], "offset": ["0%", "100%"] }, 68 | { "name":"Spiky Naga", "angle":-90, "colors": ["#505285", "#585e92", "#65689f", "#7474b0", "#7e7ebb", "#8389c7", "#9795d4", "#a2a1dc", "#b5aee4"], "offset": ["0%", "12%", "25%", "37%", "50%", "62%", "75%", "87%", "100%"] }, 69 | { "name":"Love Kiss", "angle":-90, "colors": ["#ff0844", "#ffb199"], "offset": ["0%", "100%"] }, 70 | { "name":"Clean Mirror", "angle":-45, "colors": ["#93a5cf", "#e4efe9"], "offset": ["0%", "100%"] }, 71 | { "name":"Premium Dark", "angle":0, "colors": ["#434343", "black"], "offset": ["0%", "100%"] }, 72 | { "name":"Cold Evening", "angle":-90, "colors": ["#0c3483", "#a2b6df", "#6b8cce", "#a2b6df"], "offset": ["0%", "100%", "100%", "100%"] }, 73 | { "name":"Cochiti Lake", "angle":-45, "colors": ["#93a5cf", "#e4efe9"], "offset": ["0%", "100%"] }, 74 | { "name":"Summer Games", "angle":0, "colors": ["#92fe9d", "#00c9ff"], "offset": ["0%", "100%"] }, 75 | { "name":"Passionate Bed", "angle":0, "colors": ["#ff758c", "#ff7eb3"], "offset": ["0%", "100%"] }, 76 | { "name":"Mountain Rock", "angle":0, "colors": ["#868f96", "#596164"], "offset": ["0%", "100%"] }, 77 | { "name":"Desert Hump", "angle":-90, "colors": ["#c79081", "#dfa579"], "offset": ["0%", "100%"] }, 78 | { "name":"Jungle Day", "angle":-45, "colors": ["#8baaaa", "#ae8b9c"], "offset": ["0%", "100%"] }, 79 | { "name":"Phoenix Start", "angle":0, "colors": ["#f83600", "#f9d423"], "offset": ["0%", "100%"] }, 80 | { "name":"October Silence", "angle":-110, "colors": ["#b721ff", "#21d4fd"], "offset": ["0%", "100%"] }, 81 | { "name":"Faraway River", "angle":-110, "colors": ["#6e45e2", "#88d3ce"], "offset": ["0%", "100%"] }, 82 | { "name":"Alchemist Lab", "angle":-110, "colors": ["#d558c8", "#24d292"], "offset": ["0%", "100%"] }, 83 | { "name":"Over Sun", "angle":-30, "colors": ["#abecd6", "#fbed96"], "offset": ["0%", "100%"] }, 84 | { "name":"Premium White", "angle":-90, "colors": ["#d5d4d0", "#d5d4d0", "#eeeeec", "#efeeec", "#e9e9e7"], "offset": ["0%", "1%", "31%", "75%", "100%"] }, 85 | { "name":"Mars Party", "angle":-90, "colors": ["#5f72bd", "#9b23ea"], "offset": ["0%", "100%"] }, 86 | { "name":"Eternal Constance", "angle":-90, "colors": ["#09203f", "#537895"], "offset": ["0%", "100%"] }, 87 | { "name":"Japan Blush", "angle":-110, "colors": ["#ddd6f3", "#faaca8", "#faaca8"], "offset": ["0%", "100%", "100%"] }, 88 | { "name":"Smiling Rain", "angle":-110, "colors": ["#dcb0ed", "#99c99c"], "offset": ["0%", "100%"] }, 89 | { "name":"Cloudy Apple", "angle":-90, "colors": ["#f3e7e9", "#e3eeff", "#e3eeff"], "offset": ["0%", "99%", "100%"] }, 90 | { "name":"Big Mango", "angle":-90, "colors": ["#c71d6f", "#d09693"], "offset": ["0%", "100%"] }, 91 | { "name":"Healthy Water", "angle":-30, "colors": ["#96deda", "#50c9c3"], "offset": ["0%", "100%"] }, 92 | { "name":"Amour Amour", "angle":-90, "colors": ["#f77062", "#fe5196"], "offset": ["0%", "100%"] }, 93 | { "name":"Risky Concrete", "angle":-90, "colors": ["#c4c5c7", "#dcdddf", "#ebebeb"], "offset": ["0%", "52%", "100%"] }, 94 | { "name":"Strong Stick", "angle":0, "colors": ["#a8caba", "#5d4157"], "offset": ["0%", "100%"] }, 95 | { "name":"Vicious Stance", "angle":-30, "colors": ["#29323c", "#485563"], "offset": ["0%", "100%"] }, 96 | { "name":"Palo Alto", "angle":-150, "colors": ["#16a085", "#f4d03f"], "offset": ["0%", "100%"] }, 97 | { "name":"Happy Memories", "angle":-150, "colors": ["#ff5858", "#f09819"], "offset": ["0%", "100%"] }, 98 | { "name":"Midnight Bloom", "angle":-110, "colors": ["#2b5876", "#4e4376"], "offset": ["0%", "100%"] }, 99 | { "name":"Crystalline", "angle":-110, "colors": ["#00cdac", "#8ddad5"], "offset": ["0%", "100%"] }, 100 | { "name":"Party Bliss", "angle":-90, "colors": ["#4481eb", "#04befe"], "offset": ["0%", "100%"] }, 101 | { "name":"Confident Cloud", "angle":-90, "colors": ["#dad4ec", "#dad4ec", "#f3e7e9"], "offset": ["0%", "1%", "100%"] }, 102 | { "name":"Le Cocktail", "angle":-45, "colors": ["#874da2", "#c43a30"], "offset": ["0%", "100%"] }, 103 | { "name":"River City", "angle":-90, "colors": ["#4481eb", "#04befe"], "offset": ["0%", "100%"] }, 104 | { "name":"Frozen Berry", "angle":-90, "colors": ["#e8198b", "#c7eafd"], "offset": ["0%", "100%"] }, 105 | { "name":"Child Care", "angle":-110, "colors": ["#f794a4", "#fdd6bd"], "offset": ["0%", "100%"] }, 106 | { "name":"Flying Lemon", "angle":-30, "colors": ["#64b3f4", "#c2e59c"], "offset": ["0%", "100%"] }, 107 | { "name":"New Retrowave", "angle":-90, "colors": ["#3b41c5", "#a981bb", "#ffc8a9"], "offset": ["0%", "49%", "100%"] }, 108 | { "name":"Hidden Jaguar", "angle":-90, "colors": ["#0fd850", "#f9f047"], "offset": ["0%", "100%"] }, 109 | { "name":"Above The Sky", "angle":-90, "colors": ["lightgrey", "lightgrey", "#e0e0e0", "#efefef", "#d9d9d9", "#bcbcbc"], "offset": ["0%", "1%", "26%", "48%", "75%", "100%"] }, 110 | { "name":"Nega", "angle":-45, "colors": ["#ee9ca7", "#ffdde1"], "offset": ["0%", "100%"] }, 111 | { "name":"Dense Water", "angle":0, "colors": ["#3ab5b0", "#3d99be", "#56317a"], "offset": ["0%", "31%", "100%"] }, 112 | { "name":"Seashore", "angle":-90, "colors": ["#209cff", "#68e0cf"], "offset": ["0%", "100%"] }, 113 | { "name":"Marble Wall", "angle":-90, "colors": ["#bdc2e8", "#bdc2e8", "#e6dee9"], "offset": ["0%", "1%", "100%"] }, 114 | { "name":"Cheerful Caramel", "angle":-90, "colors": ["#e6b980", "#eacda3"], "offset": ["0%", "100%"] }, 115 | { "name":"Night Sky", "angle":-90, "colors": ["#1e3c72", "#1e3c72", "#2a5298"], "offset": ["0%", "1%", "100%"] }, 116 | { "name":"Magic Lake", "angle":-90, "colors": ["#d5dee7", "#ffafbd", "#c9ffbf"], "offset": ["0%", "0%", "100%"] }, 117 | { "name":"Young Grass", "angle":-90, "colors": ["#9be15d", "#00e3ae"], "offset": ["0%", "100%"] }, 118 | { "name":"Colorful Peach", "angle":0, "colors": ["#ed6ea0", "#ec8c69"], "offset": ["0%", "100%"] }, 119 | { "name":"Gentle Care", "angle":0, "colors": ["#ffc3a0", "#ffafbd"], "offset": ["0%", "100%"] }, 120 | { "name":"Plum Bath", "angle":-90, "colors": ["#cc208e", "#6713d2"], "offset": ["0%", "100%"] }, 121 | { "name":"Happy Unicorn", "angle":-90, "colors": ["#b3ffab", "#12fff7"], "offset": ["0%", "100%"] }, 122 | { "name":"African Field", "angle":-90, "colors": ["#65bd60", "#5ac1a8", "#3ec6ed", "#b7ddb7", "#fef381"], "offset": ["0%", "25%", "50%", "75%", "100%"] }, 123 | { "name":"Solid Stone", "angle":0, "colors": ["#243949", "#517fa4"], "offset": ["0%", "100%"] }, 124 | { "name":"Orange Juice", "angle":-110, "colors": ["#fc6076", "#ff9a44"], "offset": ["0%", "100%"] }, 125 | { "name":"Glass Water", "angle":-90, "colors": ["#dfe9f3", "white"], "offset": ["0%", "100%"] }, 126 | { "name":"North Miracle", "angle":0, "colors": ["#00dbde", "#fc00ff"], "offset": ["0%", "100%"] }, 127 | { "name":"Fruit Blend", "angle":0, "colors": ["#f9d423", "#ff4e50"], "offset": ["0%", "100%"] }, 128 | { "name":"Millennium Pine", "angle":-90, "colors": ["#50cc7f", "#f5d100"], "offset": ["0%", "100%"] }, 129 | { "name":"High Flight", "angle":0, "colors": ["#0acffe", "#495aff"], "offset": ["0%", "100%"] }, 130 | { "name":"Mole Hall", "angle":-110, "colors": ["#616161", "#9bc5c3"], "offset": ["0%", "100%"] }, 131 | { "name":"Space Shift", "angle":-30, "colors": ["#3d3393", "#2b76b9", "#2cacd1", "#35eb93"], "offset": ["0%", "37%", "65%", "100%"] }, 132 | { "name":"Forest Inei", "angle":-90, "colors": ["#df89b5", "#bfd9fe"], "offset": ["0%", "100%"] }, 133 | { "name":"Royal Garden", "angle":0, "colors": ["#ed6ea0", "#ec8c69"], "offset": ["0%", "100%"] }, 134 | { "name":"Rich Metal", "angle":0, "colors": ["#d7d2cc", "#304352"], "offset": ["0%", "100%"] }, 135 | { "name":"Juicy Cake", "angle":-90, "colors": ["#e14fad", "#f9d423"], "offset": ["0%", "100%"] }, 136 | { "name":"Smart Indigo", "angle":-90, "colors": ["#b224ef", "#7579ff"], "offset": ["0%", "100%"] }, 137 | { "name":"Sand Strike", "angle":0, "colors": ["#c1c161", "#c1c161", "#d4d4b1"], "offset": ["0%", "0%", "100%"] }, 138 | { "name":"Norse Beauty", "angle":0, "colors": ["#ec77ab", "#7873f5"], "offset": ["0%", "100%"] }, 139 | { "name":"Aqua Guidance", "angle":-90, "colors": ["#007adf", "#00ecbc"], "offset": ["0%", "100%"] }, 140 | { "name":"Sun Veggie", "angle":-315, "colors": ["#20E2D7", "#F9FEA5"], "offset": ["0%", "100%"] }, 141 | { "name":"Sea Lord", "angle":-315, "colors": ["#2CD8D5", "#C5C1FF", "#FFBAC3"], "offset": ["0%", "56%", "100%"] }, 142 | { "name":"Black Sea", "angle":-315, "colors": ["#2CD8D5", "#6B8DD6", "#8E37D7"], "offset": ["0%", "48%", "100%"] }, 143 | { "name":"Grass Shampoo", "angle":-315, "colors": ["#DFFFCD", "#90F9C4", "#39F3BB"], "offset": ["0%", "48%", "100%"] }, 144 | { "name":"Landing Aircraft", "angle":-315, "colors": ["#5D9FFF", "#B8DCFF", "#6BBBFF"], "offset": ["0%", "48%", "100%"] }, 145 | { "name":"Witch Dance", "angle":-315, "colors": ["#A8BFFF", "#884D80"], "offset": ["0%", "100%"] }, 146 | { "name":"Sleepless Night", "angle":-315, "colors": ["#5271C4", "#B19FFF", "#ECA1FE"], "offset": ["0%", "48%", "100%"] }, 147 | { "name":"Angel Care", "angle":-315, "colors": ["#FFE29F", "#FFA99F", "#FF719A"], "offset": ["0%", "48%", "100%"] }, 148 | { "name":"Crystal River", "angle":-315, "colors": ["#22E1FF", "#1D8FE1", "#625EB1"], "offset": ["0%", "48%", "100%"] }, 149 | { "name":"Soft Lipstick", "angle":-315, "colors": ["#B6CEE8", "#F578DC"], "offset": ["0%", "100%"] }, 150 | { "name":"Salt Mountain", "angle":-315, "colors": ["#FFFEFF", "#D7FFFE"], "offset": ["0%", "100%"] }, 151 | { "name":"Perfect White", "angle":-315, "colors": ["#E3FDF5", "#FFE6FA"], "offset": ["0%", "100%"] }, 152 | { "name":"Fresh Oasis", "angle":-315, "colors": ["#7DE2FC", "#B9B6E5"], "offset": ["0%", "100%"] }, 153 | { "name":"Strict November", "angle":-315, "colors": ["#CBBACC", "#2580B3"], "offset": ["0%", "100%"] }, 154 | { "name":"Morning Salad", "angle":-315, "colors": ["#B7F8DB", "#50A7C2"], "offset": ["0%", "100%"] }, 155 | { "name":"Deep Relief", "angle":-315, "colors": ["#7085B6", "#87A7D9", "#DEF3F8"], "offset": ["0%", "50%", "100%"] }, 156 | { "name":"Sea Strike", "angle":-315, "colors": ["#77FFD2", "#6297DB", "#1EECFF"], "offset": ["0%", "48%", "100%"] }, 157 | { "name":"Night Call", "angle":-315, "colors": ["#AC32E4", "#7918F2", "#4801FF"], "offset": ["0%", "48%", "100%"] }, 158 | { "name":"Supreme Sky", "angle":-315, "colors": ["#D4FFEC", "#57F2CC", "#4596FB"], "offset": ["0%", "48%", "100%"] }, 159 | { "name":"Light Blue", "angle":-315, "colors": ["#9EFBD3", "#57E9F2", "#45D4FB"], "offset": ["0%", "48%", "100%"] }, 160 | { "name":"Mind Crawl", "angle":-315, "colors": ["#473B7B", "#3584A7", "#30D2BE"], "offset": ["0%", "51%", "100%"] }, 161 | { "name":"Lily Meadow", "angle":-315, "colors": ["#65379B", "#886AEA", "#6457C6"], "offset": ["0%", "52%", "100%"] }, 162 | { "name":"Sugar Lollipop", "angle":-315, "colors": ["#A445B2", "#D41872", "#FF0066"], "offset": ["0%", "52%", "100%"] }, 163 | { "name":"Sweet Dessert", "angle":-315, "colors": ["#7742B2", "#F180FF", "#FD8BD9"], "offset": ["0%", "52%", "100%"] }, 164 | { "name":"Magic Ray", "angle":-315, "colors": ["#FF3CAC", "#562B7C", "#2B86C5"], "offset": ["0%", "52%", "100%"] }, 165 | { "name":"Teen Party", "angle":-315, "colors": ["#FF057C", "#8D0B93", "#321575"], "offset": ["0%", "50%", "100%"] }, 166 | { "name":"Frozen Heat", "angle":-315, "colors": ["#FF057C", "#7C64D5", "#4CC3FF"], "offset": ["0%", "48%", "100%"] }, 167 | { "name":"Gagarin View", "angle":-315, "colors": ["#69EACB", "#EACCF8", "#6654F1"], "offset": ["0%", "48%", "100%"] }, 168 | { "name":"Fabled Sunset", "angle":-315, "colors": ["#231557", "#44107A", "#FF1361", "#FFF800"], "offset": ["0%", "29%", "67%", "100%"] }, 169 | { "name":"Perfect Blue", "angle":-315, "colors": ["#3D4E81", "#5753C9", "#6E7FF3"], "offset": ["0%", "48%", "100%"] } 170 | ] -------------------------------------------------------------------------------- /example/ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - boost (1.76.0) 3 | - CocoaAsyncSocket (7.6.5) 4 | - DoubleConversion (1.1.6) 5 | - FBLazyVector (0.72.10) 6 | - FBReactNativeSpec (0.72.10): 7 | - RCT-Folly (= 2021.07.22.00) 8 | - RCTRequired (= 0.72.10) 9 | - RCTTypeSafety (= 0.72.10) 10 | - React-Core (= 0.72.10) 11 | - React-jsi (= 0.72.10) 12 | - ReactCommon/turbomodule/core (= 0.72.10) 13 | - Flipper (0.182.0): 14 | - Flipper-Folly (~> 2.6) 15 | - Flipper-Boost-iOSX (1.76.0.1.11) 16 | - Flipper-DoubleConversion (3.2.0.1) 17 | - Flipper-Fmt (7.1.7) 18 | - Flipper-Folly (2.6.10): 19 | - Flipper-Boost-iOSX 20 | - Flipper-DoubleConversion 21 | - Flipper-Fmt (= 7.1.7) 22 | - Flipper-Glog 23 | - libevent (~> 2.1.12) 24 | - OpenSSL-Universal (= 1.1.1100) 25 | - Flipper-Glog (0.5.0.5) 26 | - Flipper-PeerTalk (0.0.4) 27 | - FlipperKit (0.182.0): 28 | - FlipperKit/Core (= 0.182.0) 29 | - FlipperKit/Core (0.182.0): 30 | - Flipper (~> 0.182.0) 31 | - FlipperKit/CppBridge 32 | - FlipperKit/FBCxxFollyDynamicConvert 33 | - FlipperKit/FBDefines 34 | - FlipperKit/FKPortForwarding 35 | - SocketRocket (~> 0.6.0) 36 | - FlipperKit/CppBridge (0.182.0): 37 | - Flipper (~> 0.182.0) 38 | - FlipperKit/FBCxxFollyDynamicConvert (0.182.0): 39 | - Flipper-Folly (~> 2.6) 40 | - FlipperKit/FBDefines (0.182.0) 41 | - FlipperKit/FKPortForwarding (0.182.0): 42 | - CocoaAsyncSocket (~> 7.6) 43 | - Flipper-PeerTalk (~> 0.0.4) 44 | - FlipperKit/FlipperKitHighlightOverlay (0.182.0) 45 | - FlipperKit/FlipperKitLayoutHelpers (0.182.0): 46 | - FlipperKit/Core 47 | - FlipperKit/FlipperKitHighlightOverlay 48 | - FlipperKit/FlipperKitLayoutTextSearchable 49 | - FlipperKit/FlipperKitLayoutIOSDescriptors (0.182.0): 50 | - FlipperKit/Core 51 | - FlipperKit/FlipperKitHighlightOverlay 52 | - FlipperKit/FlipperKitLayoutHelpers 53 | - YogaKit (~> 1.18) 54 | - FlipperKit/FlipperKitLayoutPlugin (0.182.0): 55 | - FlipperKit/Core 56 | - FlipperKit/FlipperKitHighlightOverlay 57 | - FlipperKit/FlipperKitLayoutHelpers 58 | - FlipperKit/FlipperKitLayoutIOSDescriptors 59 | - FlipperKit/FlipperKitLayoutTextSearchable 60 | - YogaKit (~> 1.18) 61 | - FlipperKit/FlipperKitLayoutTextSearchable (0.182.0) 62 | - FlipperKit/FlipperKitNetworkPlugin (0.182.0): 63 | - FlipperKit/Core 64 | - FlipperKit/FlipperKitReactPlugin (0.182.0): 65 | - FlipperKit/Core 66 | - FlipperKit/FlipperKitUserDefaultsPlugin (0.182.0): 67 | - FlipperKit/Core 68 | - FlipperKit/SKIOSNetworkPlugin (0.182.0): 69 | - FlipperKit/Core 70 | - FlipperKit/FlipperKitNetworkPlugin 71 | - fmt (6.2.1) 72 | - glog (0.3.5) 73 | - hermes-engine (0.72.10): 74 | - hermes-engine/Pre-built (= 0.72.10) 75 | - hermes-engine/Pre-built (0.72.10) 76 | - libevent (2.1.12) 77 | - OpenSSL-Universal (1.1.1100) 78 | - RCT-Folly (2021.07.22.00): 79 | - boost 80 | - DoubleConversion 81 | - fmt (~> 6.2.1) 82 | - glog 83 | - RCT-Folly/Default (= 2021.07.22.00) 84 | - RCT-Folly/Default (2021.07.22.00): 85 | - boost 86 | - DoubleConversion 87 | - fmt (~> 6.2.1) 88 | - glog 89 | - RCT-Folly/Futures (2021.07.22.00): 90 | - boost 91 | - DoubleConversion 92 | - fmt (~> 6.2.1) 93 | - glog 94 | - libevent 95 | - RCTRequired (0.72.10) 96 | - RCTTypeSafety (0.72.10): 97 | - FBLazyVector (= 0.72.10) 98 | - RCTRequired (= 0.72.10) 99 | - React-Core (= 0.72.10) 100 | - React (0.72.10): 101 | - React-Core (= 0.72.10) 102 | - React-Core/DevSupport (= 0.72.10) 103 | - React-Core/RCTWebSocket (= 0.72.10) 104 | - React-RCTActionSheet (= 0.72.10) 105 | - React-RCTAnimation (= 0.72.10) 106 | - React-RCTBlob (= 0.72.10) 107 | - React-RCTImage (= 0.72.10) 108 | - React-RCTLinking (= 0.72.10) 109 | - React-RCTNetwork (= 0.72.10) 110 | - React-RCTSettings (= 0.72.10) 111 | - React-RCTText (= 0.72.10) 112 | - React-RCTVibration (= 0.72.10) 113 | - React-callinvoker (0.72.10) 114 | - React-Codegen (0.72.10): 115 | - DoubleConversion 116 | - FBReactNativeSpec 117 | - glog 118 | - hermes-engine 119 | - RCT-Folly 120 | - RCTRequired 121 | - RCTTypeSafety 122 | - React-Core 123 | - React-jsi 124 | - React-jsiexecutor 125 | - React-NativeModulesApple 126 | - React-rncore 127 | - ReactCommon/turbomodule/bridging 128 | - ReactCommon/turbomodule/core 129 | - React-Core (0.72.10): 130 | - glog 131 | - hermes-engine 132 | - RCT-Folly (= 2021.07.22.00) 133 | - React-Core/Default (= 0.72.10) 134 | - React-cxxreact 135 | - React-hermes 136 | - React-jsi 137 | - React-jsiexecutor 138 | - React-perflogger 139 | - React-runtimeexecutor 140 | - React-utils 141 | - SocketRocket (= 0.6.1) 142 | - Yoga 143 | - React-Core/CoreModulesHeaders (0.72.10): 144 | - glog 145 | - hermes-engine 146 | - RCT-Folly (= 2021.07.22.00) 147 | - React-Core/Default 148 | - React-cxxreact 149 | - React-hermes 150 | - React-jsi 151 | - React-jsiexecutor 152 | - React-perflogger 153 | - React-runtimeexecutor 154 | - React-utils 155 | - SocketRocket (= 0.6.1) 156 | - Yoga 157 | - React-Core/Default (0.72.10): 158 | - glog 159 | - hermes-engine 160 | - RCT-Folly (= 2021.07.22.00) 161 | - React-cxxreact 162 | - React-hermes 163 | - React-jsi 164 | - React-jsiexecutor 165 | - React-perflogger 166 | - React-runtimeexecutor 167 | - React-utils 168 | - SocketRocket (= 0.6.1) 169 | - Yoga 170 | - React-Core/DevSupport (0.72.10): 171 | - glog 172 | - hermes-engine 173 | - RCT-Folly (= 2021.07.22.00) 174 | - React-Core/Default (= 0.72.10) 175 | - React-Core/RCTWebSocket (= 0.72.10) 176 | - React-cxxreact 177 | - React-hermes 178 | - React-jsi 179 | - React-jsiexecutor 180 | - React-jsinspector (= 0.72.10) 181 | - React-perflogger 182 | - React-runtimeexecutor 183 | - React-utils 184 | - SocketRocket (= 0.6.1) 185 | - Yoga 186 | - React-Core/RCTActionSheetHeaders (0.72.10): 187 | - glog 188 | - hermes-engine 189 | - RCT-Folly (= 2021.07.22.00) 190 | - React-Core/Default 191 | - React-cxxreact 192 | - React-hermes 193 | - React-jsi 194 | - React-jsiexecutor 195 | - React-perflogger 196 | - React-runtimeexecutor 197 | - React-utils 198 | - SocketRocket (= 0.6.1) 199 | - Yoga 200 | - React-Core/RCTAnimationHeaders (0.72.10): 201 | - glog 202 | - hermes-engine 203 | - RCT-Folly (= 2021.07.22.00) 204 | - React-Core/Default 205 | - React-cxxreact 206 | - React-hermes 207 | - React-jsi 208 | - React-jsiexecutor 209 | - React-perflogger 210 | - React-runtimeexecutor 211 | - React-utils 212 | - SocketRocket (= 0.6.1) 213 | - Yoga 214 | - React-Core/RCTBlobHeaders (0.72.10): 215 | - glog 216 | - hermes-engine 217 | - RCT-Folly (= 2021.07.22.00) 218 | - React-Core/Default 219 | - React-cxxreact 220 | - React-hermes 221 | - React-jsi 222 | - React-jsiexecutor 223 | - React-perflogger 224 | - React-runtimeexecutor 225 | - React-utils 226 | - SocketRocket (= 0.6.1) 227 | - Yoga 228 | - React-Core/RCTImageHeaders (0.72.10): 229 | - glog 230 | - hermes-engine 231 | - RCT-Folly (= 2021.07.22.00) 232 | - React-Core/Default 233 | - React-cxxreact 234 | - React-hermes 235 | - React-jsi 236 | - React-jsiexecutor 237 | - React-perflogger 238 | - React-runtimeexecutor 239 | - React-utils 240 | - SocketRocket (= 0.6.1) 241 | - Yoga 242 | - React-Core/RCTLinkingHeaders (0.72.10): 243 | - glog 244 | - hermes-engine 245 | - RCT-Folly (= 2021.07.22.00) 246 | - React-Core/Default 247 | - React-cxxreact 248 | - React-hermes 249 | - React-jsi 250 | - React-jsiexecutor 251 | - React-perflogger 252 | - React-runtimeexecutor 253 | - React-utils 254 | - SocketRocket (= 0.6.1) 255 | - Yoga 256 | - React-Core/RCTNetworkHeaders (0.72.10): 257 | - glog 258 | - hermes-engine 259 | - RCT-Folly (= 2021.07.22.00) 260 | - React-Core/Default 261 | - React-cxxreact 262 | - React-hermes 263 | - React-jsi 264 | - React-jsiexecutor 265 | - React-perflogger 266 | - React-runtimeexecutor 267 | - React-utils 268 | - SocketRocket (= 0.6.1) 269 | - Yoga 270 | - React-Core/RCTSettingsHeaders (0.72.10): 271 | - glog 272 | - hermes-engine 273 | - RCT-Folly (= 2021.07.22.00) 274 | - React-Core/Default 275 | - React-cxxreact 276 | - React-hermes 277 | - React-jsi 278 | - React-jsiexecutor 279 | - React-perflogger 280 | - React-runtimeexecutor 281 | - React-utils 282 | - SocketRocket (= 0.6.1) 283 | - Yoga 284 | - React-Core/RCTTextHeaders (0.72.10): 285 | - glog 286 | - hermes-engine 287 | - RCT-Folly (= 2021.07.22.00) 288 | - React-Core/Default 289 | - React-cxxreact 290 | - React-hermes 291 | - React-jsi 292 | - React-jsiexecutor 293 | - React-perflogger 294 | - React-runtimeexecutor 295 | - React-utils 296 | - SocketRocket (= 0.6.1) 297 | - Yoga 298 | - React-Core/RCTVibrationHeaders (0.72.10): 299 | - glog 300 | - hermes-engine 301 | - RCT-Folly (= 2021.07.22.00) 302 | - React-Core/Default 303 | - React-cxxreact 304 | - React-hermes 305 | - React-jsi 306 | - React-jsiexecutor 307 | - React-perflogger 308 | - React-runtimeexecutor 309 | - React-utils 310 | - SocketRocket (= 0.6.1) 311 | - Yoga 312 | - React-Core/RCTWebSocket (0.72.10): 313 | - glog 314 | - hermes-engine 315 | - RCT-Folly (= 2021.07.22.00) 316 | - React-Core/Default (= 0.72.10) 317 | - React-cxxreact 318 | - React-hermes 319 | - React-jsi 320 | - React-jsiexecutor 321 | - React-perflogger 322 | - React-runtimeexecutor 323 | - React-utils 324 | - SocketRocket (= 0.6.1) 325 | - Yoga 326 | - React-CoreModules (0.72.10): 327 | - RCT-Folly (= 2021.07.22.00) 328 | - RCTTypeSafety (= 0.72.10) 329 | - React-Codegen (= 0.72.10) 330 | - React-Core/CoreModulesHeaders (= 0.72.10) 331 | - React-jsi (= 0.72.10) 332 | - React-RCTBlob 333 | - React-RCTImage (= 0.72.10) 334 | - ReactCommon/turbomodule/core (= 0.72.10) 335 | - SocketRocket (= 0.6.1) 336 | - React-cxxreact (0.72.10): 337 | - boost (= 1.76.0) 338 | - DoubleConversion 339 | - glog 340 | - hermes-engine 341 | - RCT-Folly (= 2021.07.22.00) 342 | - React-callinvoker (= 0.72.10) 343 | - React-debug (= 0.72.10) 344 | - React-jsi (= 0.72.10) 345 | - React-jsinspector (= 0.72.10) 346 | - React-logger (= 0.72.10) 347 | - React-perflogger (= 0.72.10) 348 | - React-runtimeexecutor (= 0.72.10) 349 | - React-debug (0.72.10) 350 | - React-hermes (0.72.10): 351 | - DoubleConversion 352 | - glog 353 | - hermes-engine 354 | - RCT-Folly (= 2021.07.22.00) 355 | - RCT-Folly/Futures (= 2021.07.22.00) 356 | - React-cxxreact (= 0.72.10) 357 | - React-jsi 358 | - React-jsiexecutor (= 0.72.10) 359 | - React-jsinspector (= 0.72.10) 360 | - React-perflogger (= 0.72.10) 361 | - React-jsi (0.72.10): 362 | - boost (= 1.76.0) 363 | - DoubleConversion 364 | - glog 365 | - hermes-engine 366 | - RCT-Folly (= 2021.07.22.00) 367 | - React-jsiexecutor (0.72.10): 368 | - DoubleConversion 369 | - glog 370 | - hermes-engine 371 | - RCT-Folly (= 2021.07.22.00) 372 | - React-cxxreact (= 0.72.10) 373 | - React-jsi (= 0.72.10) 374 | - React-perflogger (= 0.72.10) 375 | - React-jsinspector (0.72.10) 376 | - React-logger (0.72.10): 377 | - glog 378 | - React-NativeModulesApple (0.72.10): 379 | - hermes-engine 380 | - React-callinvoker 381 | - React-Core 382 | - React-cxxreact 383 | - React-jsi 384 | - React-runtimeexecutor 385 | - ReactCommon/turbomodule/bridging 386 | - ReactCommon/turbomodule/core 387 | - React-perflogger (0.72.10) 388 | - React-RCTActionSheet (0.72.10): 389 | - React-Core/RCTActionSheetHeaders (= 0.72.10) 390 | - React-RCTAnimation (0.72.10): 391 | - RCT-Folly (= 2021.07.22.00) 392 | - RCTTypeSafety (= 0.72.10) 393 | - React-Codegen (= 0.72.10) 394 | - React-Core/RCTAnimationHeaders (= 0.72.10) 395 | - React-jsi (= 0.72.10) 396 | - ReactCommon/turbomodule/core (= 0.72.10) 397 | - React-RCTAppDelegate (0.72.10): 398 | - RCT-Folly 399 | - RCTRequired 400 | - RCTTypeSafety 401 | - React-Core 402 | - React-CoreModules 403 | - React-hermes 404 | - React-NativeModulesApple 405 | - React-RCTImage 406 | - React-RCTNetwork 407 | - React-runtimescheduler 408 | - ReactCommon/turbomodule/core 409 | - React-RCTBlob (0.72.10): 410 | - hermes-engine 411 | - RCT-Folly (= 2021.07.22.00) 412 | - React-Codegen (= 0.72.10) 413 | - React-Core/RCTBlobHeaders (= 0.72.10) 414 | - React-Core/RCTWebSocket (= 0.72.10) 415 | - React-jsi (= 0.72.10) 416 | - React-RCTNetwork (= 0.72.10) 417 | - ReactCommon/turbomodule/core (= 0.72.10) 418 | - React-RCTImage (0.72.10): 419 | - RCT-Folly (= 2021.07.22.00) 420 | - RCTTypeSafety (= 0.72.10) 421 | - React-Codegen (= 0.72.10) 422 | - React-Core/RCTImageHeaders (= 0.72.10) 423 | - React-jsi (= 0.72.10) 424 | - React-RCTNetwork (= 0.72.10) 425 | - ReactCommon/turbomodule/core (= 0.72.10) 426 | - React-RCTLinking (0.72.10): 427 | - React-Codegen (= 0.72.10) 428 | - React-Core/RCTLinkingHeaders (= 0.72.10) 429 | - React-jsi (= 0.72.10) 430 | - ReactCommon/turbomodule/core (= 0.72.10) 431 | - React-RCTNetwork (0.72.10): 432 | - RCT-Folly (= 2021.07.22.00) 433 | - RCTTypeSafety (= 0.72.10) 434 | - React-Codegen (= 0.72.10) 435 | - React-Core/RCTNetworkHeaders (= 0.72.10) 436 | - React-jsi (= 0.72.10) 437 | - ReactCommon/turbomodule/core (= 0.72.10) 438 | - React-RCTSettings (0.72.10): 439 | - RCT-Folly (= 2021.07.22.00) 440 | - RCTTypeSafety (= 0.72.10) 441 | - React-Codegen (= 0.72.10) 442 | - React-Core/RCTSettingsHeaders (= 0.72.10) 443 | - React-jsi (= 0.72.10) 444 | - ReactCommon/turbomodule/core (= 0.72.10) 445 | - React-RCTText (0.72.10): 446 | - React-Core/RCTTextHeaders (= 0.72.10) 447 | - React-RCTVibration (0.72.10): 448 | - RCT-Folly (= 2021.07.22.00) 449 | - React-Codegen (= 0.72.10) 450 | - React-Core/RCTVibrationHeaders (= 0.72.10) 451 | - React-jsi (= 0.72.10) 452 | - ReactCommon/turbomodule/core (= 0.72.10) 453 | - React-rncore (0.72.10) 454 | - React-runtimeexecutor (0.72.10): 455 | - React-jsi (= 0.72.10) 456 | - React-runtimescheduler (0.72.10): 457 | - glog 458 | - hermes-engine 459 | - RCT-Folly (= 2021.07.22.00) 460 | - React-callinvoker 461 | - React-debug 462 | - React-jsi 463 | - React-runtimeexecutor 464 | - React-utils (0.72.10): 465 | - glog 466 | - RCT-Folly (= 2021.07.22.00) 467 | - React-debug 468 | - ReactCommon/turbomodule/bridging (0.72.10): 469 | - DoubleConversion 470 | - glog 471 | - hermes-engine 472 | - RCT-Folly (= 2021.07.22.00) 473 | - React-callinvoker (= 0.72.10) 474 | - React-cxxreact (= 0.72.10) 475 | - React-jsi (= 0.72.10) 476 | - React-logger (= 0.72.10) 477 | - React-perflogger (= 0.72.10) 478 | - ReactCommon/turbomodule/core (0.72.10): 479 | - DoubleConversion 480 | - glog 481 | - hermes-engine 482 | - RCT-Folly (= 2021.07.22.00) 483 | - React-callinvoker (= 0.72.10) 484 | - React-cxxreact (= 0.72.10) 485 | - React-jsi (= 0.72.10) 486 | - React-logger (= 0.72.10) 487 | - React-perflogger (= 0.72.10) 488 | - RNSVG (14.1.0): 489 | - React-Core 490 | - SocketRocket (0.6.1) 491 | - Yoga (1.14.0) 492 | - YogaKit (1.18.1): 493 | - Yoga (~> 1.14) 494 | 495 | DEPENDENCIES: 496 | - boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`) 497 | - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) 498 | - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`) 499 | - FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`) 500 | - Flipper (= 0.182.0) 501 | - Flipper-Boost-iOSX (= 1.76.0.1.11) 502 | - Flipper-DoubleConversion (= 3.2.0.1) 503 | - Flipper-Fmt (= 7.1.7) 504 | - Flipper-Folly (= 2.6.10) 505 | - Flipper-Glog (= 0.5.0.5) 506 | - Flipper-PeerTalk (= 0.0.4) 507 | - FlipperKit (= 0.182.0) 508 | - FlipperKit/Core (= 0.182.0) 509 | - FlipperKit/CppBridge (= 0.182.0) 510 | - FlipperKit/FBCxxFollyDynamicConvert (= 0.182.0) 511 | - FlipperKit/FBDefines (= 0.182.0) 512 | - FlipperKit/FKPortForwarding (= 0.182.0) 513 | - FlipperKit/FlipperKitHighlightOverlay (= 0.182.0) 514 | - FlipperKit/FlipperKitLayoutPlugin (= 0.182.0) 515 | - FlipperKit/FlipperKitLayoutTextSearchable (= 0.182.0) 516 | - FlipperKit/FlipperKitNetworkPlugin (= 0.182.0) 517 | - FlipperKit/FlipperKitReactPlugin (= 0.182.0) 518 | - FlipperKit/FlipperKitUserDefaultsPlugin (= 0.182.0) 519 | - FlipperKit/SKIOSNetworkPlugin (= 0.182.0) 520 | - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) 521 | - hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`) 522 | - libevent (~> 2.1.12) 523 | - OpenSSL-Universal (= 1.1.1100) 524 | - RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) 525 | - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`) 526 | - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`) 527 | - React (from `../node_modules/react-native/`) 528 | - React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`) 529 | - React-Codegen (from `build/generated/ios`) 530 | - React-Core (from `../node_modules/react-native/`) 531 | - React-Core/DevSupport (from `../node_modules/react-native/`) 532 | - React-Core/RCTWebSocket (from `../node_modules/react-native/`) 533 | - React-CoreModules (from `../node_modules/react-native/React/CoreModules`) 534 | - React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`) 535 | - React-debug (from `../node_modules/react-native/ReactCommon/react/debug`) 536 | - React-hermes (from `../node_modules/react-native/ReactCommon/hermes`) 537 | - React-jsi (from `../node_modules/react-native/ReactCommon/jsi`) 538 | - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`) 539 | - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`) 540 | - React-logger (from `../node_modules/react-native/ReactCommon/logger`) 541 | - React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`) 542 | - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`) 543 | - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) 544 | - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`) 545 | - React-RCTAppDelegate (from `../node_modules/react-native/Libraries/AppDelegate`) 546 | - React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`) 547 | - React-RCTImage (from `../node_modules/react-native/Libraries/Image`) 548 | - React-RCTLinking (from `../node_modules/react-native/Libraries/LinkingIOS`) 549 | - React-RCTNetwork (from `../node_modules/react-native/Libraries/Network`) 550 | - React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`) 551 | - React-RCTText (from `../node_modules/react-native/Libraries/Text`) 552 | - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`) 553 | - React-rncore (from `../node_modules/react-native/ReactCommon`) 554 | - React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`) 555 | - React-runtimescheduler (from `../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler`) 556 | - React-utils (from `../node_modules/react-native/ReactCommon/react/utils`) 557 | - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) 558 | - RNSVG (from `../node_modules/react-native-svg`) 559 | - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) 560 | 561 | SPEC REPOS: 562 | trunk: 563 | - CocoaAsyncSocket 564 | - Flipper 565 | - Flipper-Boost-iOSX 566 | - Flipper-DoubleConversion 567 | - Flipper-Fmt 568 | - Flipper-Folly 569 | - Flipper-Glog 570 | - Flipper-PeerTalk 571 | - FlipperKit 572 | - fmt 573 | - libevent 574 | - OpenSSL-Universal 575 | - SocketRocket 576 | - YogaKit 577 | 578 | EXTERNAL SOURCES: 579 | boost: 580 | :podspec: "../node_modules/react-native/third-party-podspecs/boost.podspec" 581 | DoubleConversion: 582 | :podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec" 583 | FBLazyVector: 584 | :path: "../node_modules/react-native/Libraries/FBLazyVector" 585 | FBReactNativeSpec: 586 | :path: "../node_modules/react-native/React/FBReactNativeSpec" 587 | glog: 588 | :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" 589 | hermes-engine: 590 | :podspec: "../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec" 591 | RCT-Folly: 592 | :podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec" 593 | RCTRequired: 594 | :path: "../node_modules/react-native/Libraries/RCTRequired" 595 | RCTTypeSafety: 596 | :path: "../node_modules/react-native/Libraries/TypeSafety" 597 | React: 598 | :path: "../node_modules/react-native/" 599 | React-callinvoker: 600 | :path: "../node_modules/react-native/ReactCommon/callinvoker" 601 | React-Codegen: 602 | :path: build/generated/ios 603 | React-Core: 604 | :path: "../node_modules/react-native/" 605 | React-CoreModules: 606 | :path: "../node_modules/react-native/React/CoreModules" 607 | React-cxxreact: 608 | :path: "../node_modules/react-native/ReactCommon/cxxreact" 609 | React-debug: 610 | :path: "../node_modules/react-native/ReactCommon/react/debug" 611 | React-hermes: 612 | :path: "../node_modules/react-native/ReactCommon/hermes" 613 | React-jsi: 614 | :path: "../node_modules/react-native/ReactCommon/jsi" 615 | React-jsiexecutor: 616 | :path: "../node_modules/react-native/ReactCommon/jsiexecutor" 617 | React-jsinspector: 618 | :path: "../node_modules/react-native/ReactCommon/jsinspector" 619 | React-logger: 620 | :path: "../node_modules/react-native/ReactCommon/logger" 621 | React-NativeModulesApple: 622 | :path: "../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios" 623 | React-perflogger: 624 | :path: "../node_modules/react-native/ReactCommon/reactperflogger" 625 | React-RCTActionSheet: 626 | :path: "../node_modules/react-native/Libraries/ActionSheetIOS" 627 | React-RCTAnimation: 628 | :path: "../node_modules/react-native/Libraries/NativeAnimation" 629 | React-RCTAppDelegate: 630 | :path: "../node_modules/react-native/Libraries/AppDelegate" 631 | React-RCTBlob: 632 | :path: "../node_modules/react-native/Libraries/Blob" 633 | React-RCTImage: 634 | :path: "../node_modules/react-native/Libraries/Image" 635 | React-RCTLinking: 636 | :path: "../node_modules/react-native/Libraries/LinkingIOS" 637 | React-RCTNetwork: 638 | :path: "../node_modules/react-native/Libraries/Network" 639 | React-RCTSettings: 640 | :path: "../node_modules/react-native/Libraries/Settings" 641 | React-RCTText: 642 | :path: "../node_modules/react-native/Libraries/Text" 643 | React-RCTVibration: 644 | :path: "../node_modules/react-native/Libraries/Vibration" 645 | React-rncore: 646 | :path: "../node_modules/react-native/ReactCommon" 647 | React-runtimeexecutor: 648 | :path: "../node_modules/react-native/ReactCommon/runtimeexecutor" 649 | React-runtimescheduler: 650 | :path: "../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler" 651 | React-utils: 652 | :path: "../node_modules/react-native/ReactCommon/react/utils" 653 | ReactCommon: 654 | :path: "../node_modules/react-native/ReactCommon" 655 | RNSVG: 656 | :path: "../node_modules/react-native-svg" 657 | Yoga: 658 | :path: "../node_modules/react-native/ReactCommon/yoga" 659 | 660 | SPEC CHECKSUMS: 661 | boost: 7dcd2de282d72e344012f7d6564d024930a6a440 662 | CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 663 | DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54 664 | FBLazyVector: f91d538f197fa71a7d5b77ec2069d49550c0eb96 665 | FBReactNativeSpec: b13d1c23d6ed82d6b66aad7a253edf8ba76c4a4c 666 | Flipper: 6edb735e6c3e332975d1b17956bcc584eccf5818 667 | Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c 668 | Flipper-DoubleConversion: 2dc99b02f658daf147069aad9dbd29d8feb06d30 669 | Flipper-Fmt: 60cbdd92fc254826e61d669a5d87ef7015396a9b 670 | Flipper-Folly: 584845625005ff068a6ebf41f857f468decd26b3 671 | Flipper-Glog: 70c50ce58ddaf67dc35180db05f191692570f446 672 | Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9 673 | FlipperKit: 2efad7007d6745a3f95e4034d547be637f89d3f6 674 | fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 675 | glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b 676 | hermes-engine: 90e4033deb00bee33330a9f15eff0f874bd82f6d 677 | libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 678 | OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c 679 | RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1 680 | RCTRequired: b4d3068afa6f52ec5260a8417053b1f1b421483d 681 | RCTTypeSafety: a4551b3d338c96435f63bf06d564055c1d3cc0ac 682 | React: 66caa2a8192a35d7ba466a5fdf5dc06ee4a5f6dd 683 | React-callinvoker: e5b55e46894c2dd1bcdc19d4f82b0f7f631d1237 684 | React-Codegen: 0cf41e00026c5eba61f6bdcabd6e4bf659754f33 685 | React-Core: 2ce84187a00913f287b96753c56c7819ed7d90d5 686 | React-CoreModules: 893e7c5eed1ef8fe9e1ee1d913581c946e55b305 687 | React-cxxreact: 075d98dc664c0e9607cc0c45d41dc052bcc7313b 688 | React-debug: abc6213dcb9eafcf5242cbb194fef4c70c91871f 689 | React-hermes: 133cfa220ef836406f693ed7db56a509032ce433 690 | React-jsi: 9b45fd040d575f8ae6771bf1960641a58eb0bdd4 691 | React-jsiexecutor: 45ef2ec6dcde31b90469175ec76ddac77b91dfc3 692 | React-jsinspector: de0198127395fec3058140a20c045167f761bb16 693 | React-logger: dc3a2b174d79c2da635059212747d8d929b54e06 694 | React-NativeModulesApple: c3e696ff867e4bc212266cbdf7e862e48a0166fd 695 | React-perflogger: 43287389ea08993c300897a46f95cfac04bb6c1a 696 | React-RCTActionSheet: 923afe77f9bb89da7c1f98e2730bfc9dde0eed6d 697 | React-RCTAnimation: afd4d94c5e1f731e32ac99800850be06564ac642 698 | React-RCTAppDelegate: fb2e1447d014557f29e214fe2eb777442f808a3b 699 | React-RCTBlob: 167e2c6c3643f093058c51e76ecc653fc8236033 700 | React-RCTImage: 867de82a17630a08a3fa64b0cd6677dd19bf6eaf 701 | React-RCTLinking: 885dde8bc5d397c3e72c76315f1f9b5030b3a70e 702 | React-RCTNetwork: efec71102220b96ac8605d0253debd859ca0c817 703 | React-RCTSettings: 077065d0a4e925b017fe8538afa574d8fb52391f 704 | React-RCTText: 7adddb518ac362b2398fedf0c64105e0dab29441 705 | React-RCTVibration: de6b7218e415d82788e0965f278dddb2ef88b372 706 | React-rncore: f0d8c23481a6c263a343fa7fd3816d943754b720 707 | React-runtimeexecutor: 2b2c09edbca4c9a667428e8c93959f66b3b53140 708 | React-runtimescheduler: 6ca43e8deadf01ff06b3f01abf8f0e4d508e23c3 709 | React-utils: 372b83030a74347331636909278bf0a60ec30d59 710 | ReactCommon: 38824bfffaf4c51fbe03a2730b4fd874ef34d67b 711 | RNSVG: ba3e7232f45e34b7b47e74472386cf4e1a676d0a 712 | SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17 713 | Yoga: d0003f849d2b5224c072cef6568b540d8bb15cd3 714 | YogaKit: f782866e155069a2cca2517aafea43200b01fd5a 715 | 716 | PODFILE CHECKSUM: fc294bda6eb4bdf564e8b01f128fbe9addb961d2 717 | 718 | COCOAPODS: 1.14.3 719 | --------------------------------------------------------------------------------