diff --git a/Bar.js b/Bar.js index 637f5e1..16ec828 100644 --- a/Bar.js +++ b/Bar.js @@ -1,20 +1,17 @@ -import React, { - Component, - PropTypes, -} from 'react'; - -import { - Animated, - Easing, - View, -} from 'react-native'; +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { Animated, Easing, View, ViewPropTypes } from 'react-native'; const INDETERMINATE_WIDTH_FACTOR = 0.3; -const BAR_WIDTH_ZERO_POSITION = INDETERMINATE_WIDTH_FACTOR / (1 + INDETERMINATE_WIDTH_FACTOR); +const BAR_WIDTH_ZERO_POSITION = + INDETERMINATE_WIDTH_FACTOR / (1 + INDETERMINATE_WIDTH_FACTOR); + +const RNViewPropTypes = ViewPropTypes || View.propTypes; export default class ProgressBar extends Component { static propTypes = { animated: PropTypes.bool, + animateIncreaseOnly: PropTypes.bool, borderColor: PropTypes.string, borderRadius: PropTypes.number, borderWidth: PropTypes.number, @@ -22,14 +19,20 @@ export default class ProgressBar extends Component { color: PropTypes.string, height: PropTypes.number, indeterminate: PropTypes.bool, + onLayout: PropTypes.func, progress: PropTypes.number, - style: View.propTypes.style, + style: RNViewPropTypes.style, unfilledColor: PropTypes.string, width: PropTypes.number, + useNativeDriver: PropTypes.bool, + // eslint-disable-next-line react/forbid-prop-types + animationConfig: PropTypes.object.isRequired, + animationType: PropTypes.oneOf(['decay', 'timing', 'spring']), }; static defaultProps = { animated: true, + animateIncreaseOnly: false, borderRadius: 4, borderWidth: 1, color: 'rgba(0, 122, 255, 1)', @@ -37,13 +40,19 @@ export default class ProgressBar extends Component { indeterminate: false, progress: 0, width: 150, + useNativeDriver: false, + animationConfig: { bounciness: 0 }, + animationType: 'spring', }; constructor(props) { super(props); const progress = Math.min(Math.max(props.progress, 0), 1); this.state = { - progress: new Animated.Value(props.indeterminate ? INDETERMINATE_WIDTH_FACTOR : progress), + width: 0, + progress: new Animated.Value( + props.indeterminate ? INDETERMINATE_WIDTH_FACTOR : progress, + ), animationValue: new Animated.Value(BAR_WIDTH_ZERO_POSITION), }; } @@ -61,6 +70,7 @@ export default class ProgressBar extends Component { } else { Animated.spring(this.state.animationValue, { toValue: BAR_WIDTH_ZERO_POSITION, + useNativeDriver: props.useNativeDriver, }).start(); } } @@ -68,15 +78,18 @@ export default class ProgressBar extends Component { props.indeterminate !== this.props.indeterminate || props.progress !== this.props.progress ) { - const progress = (props.indeterminate + const progress = props.indeterminate ? INDETERMINATE_WIDTH_FACTOR - : Math.min(Math.max(props.progress, 0), 1) - ); + : Math.min(Math.max(props.progress, 0), 1); - if (props.animated) { + if ( + props.animated && + (!props.animateIncreaseOnly || + (props.animateIncreaseOnly && progress > this.props.progress)) + ) { Animated.spring(this.state.progress, { toValue: progress, - bounciness: 0, + useNativeDriver: props.useNativeDriver, }).start(); } else { this.state.progress.setValue(progress); @@ -91,13 +104,23 @@ export default class ProgressBar extends Component { duration: 1000, easing: Easing.linear, isInteraction: false, - }).start((endState) => { + useNativeDriver: this.props.useNativeDriver, + }).start(endState => { if (endState.finished) { this.animate(); } }); } + handleLayout = event => { + if (!this.props.width) { + this.setState({ width: event.nativeEvent.layout.width }); + } + if (this.props.onLayout) { + this.props.onLayout(event); + } + }; + render() { const { borderColor, @@ -112,7 +135,7 @@ export default class ProgressBar extends Component { ...restProps } = this.props; - const innerWidth = width - (borderWidth * 2); + const innerWidth = Math.max(0, width || this.state.width) - borderWidth * 2; const containerStyle = { width, borderWidth, @@ -124,24 +147,35 @@ export default class ProgressBar extends Component { const progressStyle = { backgroundColor: color, height, - width: innerWidth, - transform: [{ - translateX: this.state.animationValue.interpolate({ - inputRange: [0, 1], - outputRange: [innerWidth * -INDETERMINATE_WIDTH_FACTOR, innerWidth], - }), - }, { - translateX: this.state.progress.interpolate({ - inputRange: [0, 1], - outputRange: [innerWidth / -2, 0], - }), - }, { - scaleX: this.state.progress, - }], + transform: [ + { + translateX: this.state.animationValue.interpolate({ + inputRange: [0, 1], + outputRange: [innerWidth * -INDETERMINATE_WIDTH_FACTOR, innerWidth], + }), + }, + { + translateX: this.state.progress.interpolate({ + inputRange: [0, 1], + outputRange: [innerWidth / -2, 0], + }), + }, + { + // Interpolation a temp workaround for https://github.com/facebook/react-native/issues/6278 + scaleX: this.state.progress.interpolate({ + inputRange: [0, 1], + outputRange: [0.0001, 1], + }), + }, + ], }; return ( - + {children} diff --git a/Circle.js b/Circle.js index f88a136..ace1aea 100644 --- a/Circle.js +++ b/Circle.js @@ -1,14 +1,12 @@ -import React, { - Component, - PropTypes, -} from 'react'; - +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; import { Animated, ART, StyleSheet, Text, View, + ViewPropTypes, } from 'react-native'; import Arc from './Shapes/Arc'; @@ -19,6 +17,8 @@ const CIRCLE = Math.PI * 2; const AnimatedSurface = Animated.createAnimatedComponent(ART.Surface); const AnimatedArc = Animated.createAnimatedComponent(Arc); +const RNViewPropTypes = ViewPropTypes || View.propTypes; + const styles = StyleSheet.create({ container: { backgroundColor: 'transparent', @@ -32,7 +32,7 @@ export class ProgressCircle extends Component { borderColor: PropTypes.string, borderWidth: PropTypes.number, color: PropTypes.string, - children: React.PropTypes.node, + children: PropTypes.node, direction: PropTypes.oneOf(['clockwise', 'counter-clockwise']), formatText: PropTypes.func, indeterminate: PropTypes.bool, @@ -43,7 +43,7 @@ export class ProgressCircle extends Component { rotation: PropTypes.instanceOf(Animated.Value), showsText: PropTypes.bool, size: PropTypes.number, - style: View.propTypes.style, + style: RNViewPropTypes.style, textStyle: Text.propTypes.style, thickness: PropTypes.number, unfilledColor: PropTypes.string, @@ -92,6 +92,7 @@ export class ProgressCircle extends Component { showsText, size, style, + strokeCap, textStyle, thickness, unfilledColor, @@ -148,6 +149,7 @@ export class ProgressCircle extends Component { endAngle={angle} direction={direction} stroke={color} + strokeCap={strokeCap} strokeWidth={thickness} /> ) : false} @@ -157,6 +159,7 @@ export class ProgressCircle extends Component { startAngle={0} endAngle={(indeterminate ? 1.8 : 2) * Math.PI} stroke={borderColor || color} + strokeCap={strokeCap} strokeWidth={border} /> ) : false} diff --git a/CircleSnail.js b/CircleSnail.js index a4625e2..b9b2d47 100644 --- a/CircleSnail.js +++ b/CircleSnail.js @@ -1,13 +1,11 @@ -import React, { - Component, - PropTypes, -} from 'react'; - +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; import { Animated, ART, Easing, View, + ViewPropTypes, } from 'react-native'; import Arc from './Shapes/Arc'; @@ -17,6 +15,8 @@ const AnimatedArc = Animated.createAnimatedComponent(Arc); const MIN_ARC_ANGLE = 0.1; const MAX_ARC_ANGLE = 1.5 * Math.PI; +const RNViewPropTypes = ViewPropTypes || View.propTypes; + export default class CircleSnail extends Component { static propTypes = { animating: PropTypes.bool, @@ -30,8 +30,9 @@ export default class CircleSnail extends Component { hidesWhenStopped: PropTypes.bool, size: PropTypes.number, spinDuration: PropTypes.number, - style: View.propTypes.style, + style: RNViewPropTypes.style, thickness: PropTypes.number, + strokeCap: PropTypes.string }; static defaultProps = { @@ -41,6 +42,7 @@ export default class CircleSnail extends Component { hidesWhenStopped: false, size: 40, thickness: 3, + strokeCap: 'round' }; constructor(props) { @@ -128,6 +130,7 @@ export default class CircleSnail extends Component { size, style, thickness, + strokeCap, ...restProps } = this.props; @@ -171,7 +174,7 @@ export default class CircleSnail extends Component { offset={offset} startAngle={this.state.startAngle} endAngle={this.state.endAngle} - strokeCap="round" + strokeCap={strokeCap} strokeWidth={thickness} /> diff --git a/Example/.babelrc b/Example/.babelrc index 8df53fe..a9ce136 100644 --- a/Example/.babelrc +++ b/Example/.babelrc @@ -1,3 +1,3 @@ { -"presets": ["react-native"] -} \ No newline at end of file + "presets": ["react-native"] +} diff --git a/Example/.flowconfig b/Example/.flowconfig index 876e701..8346120 100644 --- a/Example/.flowconfig +++ b/Example/.flowconfig @@ -22,9 +22,9 @@ node_modules/react-native/flow flow/ [options] -module.system=haste +emoji=true -experimental.strict_type_args=true +module.system=haste munge_underscores=true @@ -34,11 +34,12 @@ suppress_type=$FlowIssue suppress_type=$FlowFixMe suppress_type=$FixMe -suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(3[0-6]\\|[1-2][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) -suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(3[0-6]\\|1[0-9]\\|[1-2][0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+ +suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(4[0-9]\\|[1-3][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) +suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(4[0-9]\\|[1-3][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+ suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy +suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError unsafe.enable_getters_and_setters=true [version] -^0.36.0 +^0.49.1 diff --git a/Example/.gitignore b/Example/.gitignore index fc13f16..10be197 100644 --- a/Example/.gitignore +++ b/Example/.gitignore @@ -34,11 +34,11 @@ local.properties # node_modules/ npm-debug.log +yarn-error.log # BUCK buck-out/ \.buckd/ -android/app/libs *.keystore # fastlane diff --git a/Example/android/app/BUCK b/Example/android/app/BUCK index 2ebdb98..c8f5603 100644 --- a/Example/android/app/BUCK +++ b/Example/android/app/BUCK @@ -1,5 +1,3 @@ -import re - # To learn about Buck see [Docs](https://buckbuild.com/). # To run your application with Buck: # - install Buck @@ -11,8 +9,9 @@ import re # lib_deps = [] + for jarfile in glob(['libs/*.jar']): - name = 'jars__' + re.sub(r'^.*/([^/]+)\.jar$', r'\1', jarfile) + name = 'jars__' + jarfile[jarfile.rindex('/') + 1: jarfile.rindex('.jar')] lib_deps.append(':' + name) prebuilt_jar( name = name, @@ -20,7 +19,7 @@ for jarfile in glob(['libs/*.jar']): ) for aarfile in glob(['libs/*.aar']): - name = 'aars__' + re.sub(r'^.*/([^/]+)\.aar$', r'\1', aarfile) + name = 'aars__' + aarfile[aarfile.rindex('/') + 1: aarfile.rindex('.aar')] lib_deps.append(':' + name) android_prebuilt_aar( name = name, @@ -28,39 +27,39 @@ for aarfile in glob(['libs/*.aar']): ) android_library( - name = 'all-libs', - exported_deps = lib_deps + name = "all-libs", + exported_deps = lib_deps, ) android_library( - name = 'app-code', - srcs = glob([ - 'src/main/java/**/*.java', - ]), - deps = [ - ':all-libs', - ':build_config', - ':res', - ], + name = "app-code", + srcs = glob([ + "src/main/java/**/*.java", + ]), + deps = [ + ":all-libs", + ":build_config", + ":res", + ], ) android_build_config( - name = 'build_config', - package = 'com.example', + name = "build_config", + package = "com.example", ) android_resource( - name = 'res', - res = 'src/main/res', - package = 'com.example', + name = "res", + package = "com.example", + res = "src/main/res", ) android_binary( - name = 'app', - package_type = 'debug', - manifest = 'src/main/AndroidManifest.xml', - keystore = '//android/keystores:debug', - deps = [ - ':app-code', - ], + name = "app", + keystore = "//android/keystores:debug", + manifest = "src/main/AndroidManifest.xml", + package_type = "debug", + deps = [ + ":app-code", + ], ) diff --git a/Example/android/app/build.gradle b/Example/android/app/build.gradle index 7d655dc..5cc5e59 100644 --- a/Example/android/app/build.gradle +++ b/Example/android/app/build.gradle @@ -33,6 +33,13 @@ import com.android.build.OutputFile * // bundleInPaidRelease: true, * // bundleInBeta: true, * + * // whether to disable dev mode in custom build variants (by default only disabled in release) + * // for example: to disable dev mode in the staging build type (if configured) + * devDisabledInStaging: true, + * // The configuration property can be in the following formats + * // 'devDisabledIn${productFlavor}${buildType}' + * // 'devDisabledIn${buildType}' + * * // the root of your project, i.e. where "package.json" lives * root: "../../", * @@ -58,7 +65,7 @@ import com.android.build.OutputFile * inputExcludes: ["android/**", "ios/**"], * * // override which node gets called and with what additional arguments - * nodeExecutableAndArgs: ["node"] + * nodeExecutableAndArgs: ["node"], * * // supply additional arguments to the packager * extraPackagerArgs: [] diff --git a/Example/android/app/proguard-rules.pro b/Example/android/app/proguard-rules.pro index 48361a9..6e8516c 100644 --- a/Example/android/app/proguard-rules.pro +++ b/Example/android/app/proguard-rules.pro @@ -50,6 +50,10 @@ -dontwarn com.facebook.react.** +# TextLayoutBuilder uses a non-public Android constructor within StaticLayout. +# See libs/proxy/src/main/java/com/facebook/fbui/textlayoutbuilder/proxy for details. +-dontwarn android.text.StaticLayout + # okhttp -keepattributes Signature diff --git a/Example/android/app/src/main/AndroidManifest.xml b/Example/android/app/src/main/AndroidManifest.xml index 677f075..8275835 100644 --- a/Example/android/app/src/main/AndroidManifest.xml +++ b/Example/android/app/src/main/AndroidManifest.xml @@ -19,7 +19,8 @@ + android:configChanges="keyboard|keyboardHidden|orientation|screenSize" + android:windowSoftInputMode="adjustResize"> diff --git a/Example/android/app/src/main/java/com/example/MainApplication.java b/Example/android/app/src/main/java/com/example/MainApplication.java index 4a10e25..f51721b 100644 --- a/Example/android/app/src/main/java/com/example/MainApplication.java +++ b/Example/android/app/src/main/java/com/example/MainApplication.java @@ -1,10 +1,8 @@ package com.example; import android.app.Application; -import android.util.Log; import com.facebook.react.ReactApplication; -import com.facebook.react.ReactInstanceManager; import com.facebook.react.ReactNativeHost; import com.facebook.react.ReactPackage; import com.facebook.react.shell.MainReactPackage; @@ -17,7 +15,7 @@ public class MainApplication extends Application implements ReactApplication { private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { @Override - protected boolean getUseDeveloperSupport() { + public boolean getUseDeveloperSupport() { return BuildConfig.DEBUG; } diff --git a/Example/android/build.gradle b/Example/android/build.gradle index fcba4c5..eed9972 100644 --- a/Example/android/build.gradle +++ b/Example/android/build.gradle @@ -5,7 +5,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:1.3.1' + classpath 'com.android.tools.build:gradle:2.2.3' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/Example/android/gradle/wrapper/gradle-wrapper.properties b/Example/android/gradle/wrapper/gradle-wrapper.properties index b9fbfab..dbdc05d 100644 --- a/Example/android/gradle/wrapper/gradle-wrapper.properties +++ b/Example/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip diff --git a/Example/android/keystores/BUCK b/Example/android/keystores/BUCK index 15da20e..88e4c31 100644 --- a/Example/android/keystores/BUCK +++ b/Example/android/keystores/BUCK @@ -1,8 +1,8 @@ keystore( - name = 'debug', - store = 'debug.keystore', - properties = 'debug.keystore.properties', - visibility = [ - 'PUBLIC', - ], + name = "debug", + properties = "debug.keystore.properties", + store = "debug.keystore", + visibility = [ + "PUBLIC", + ], ) diff --git a/Example/app.json b/Example/app.json new file mode 100644 index 0000000..e933d06 --- /dev/null +++ b/Example/app.json @@ -0,0 +1,4 @@ +{ + "name": "Example", + "displayName": "Example" +} \ No newline at end of file diff --git a/Example/ios/Example.xcodeproj/project.pbxproj b/Example/ios/Example.xcodeproj/project.pbxproj index 6d3a9b9..4665c7d 100644 --- a/Example/ios/Example.xcodeproj/project.pbxproj +++ b/Example/ios/Example.xcodeproj/project.pbxproj @@ -22,7 +22,7 @@ 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 140ED2AC1D01E1AD002B40FF /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; 146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; - 5D7639A71E3135C40002FDFB /* libART.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5D76398D1E3135B90002FDFB /* libART.a */; }; + 5D7D53981F4CD74900C3E091 /* libART.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5D7D53951F4CD73900C3E091 /* libART.a */; }; 5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */; }; 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; }; /* End PBXBuildFile section */ @@ -182,13 +182,48 @@ remoteGlobalIDString = 3D3CD9181DE5FBD800167DC4; remoteInfo = "jschelpers-tvOS"; }; - 5D76398C1E3135B90002FDFB /* PBXContainerItemProxy */ = { + 5D7D53871F4CD72100C3E091 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = 5D7639881E3135B90002FDFB /* ART.xcodeproj */; + containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 139D7ECE1E25DB7D00323FB7; + remoteInfo = "third-party"; + }; + 5D7D53891F4CD72100C3E091 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 3D383D3C1EBD27B6005632C8; + remoteInfo = "third-party-tvOS"; + }; + 5D7D538B1F4CD72100C3E091 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 139D7E881E25C6D100323FB7; + remoteInfo = "double-conversion"; + }; + 5D7D538D1F4CD72100C3E091 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 3D383D621EBD27B9005632C8; + remoteInfo = "double-conversion-tvOS"; + }; + 5D7D53941F4CD73900C3E091 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5D7D538F1F4CD73900C3E091 /* ART.xcodeproj */; proxyType = 2; remoteGlobalIDString = 0CF68AC11AF0540F00FF9E5C; remoteInfo = ART; }; + 5D7D53961F4CD73900C3E091 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5D7D538F1F4CD73900C3E091 /* ART.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 323A12871E5F266B004975B8; + remoteInfo = "ART-tvOS"; + }; 5E9157321DD0AC6500FF2AA8 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */; @@ -239,7 +274,7 @@ 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Example/Info.plist; sourceTree = ""; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = Example/main.m; sourceTree = ""; }; 146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = ""; }; - 5D7639881E3135B90002FDFB /* ART.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ART.xcodeproj; path = "../node_modules/react-native/Libraries/ART/ART.xcodeproj"; sourceTree = ""; }; + 5D7D538F1F4CD73900C3E091 /* ART.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ART.xcodeproj; path = "../node_modules/react-native/Libraries/ART/ART.xcodeproj"; sourceTree = ""; }; 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAnimation.xcodeproj; path = "../node_modules/react-native/Libraries/NativeAnimation/RCTAnimation.xcodeproj"; sourceTree = ""; }; 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = ""; }; 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = ""; }; @@ -258,9 +293,9 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 5D7639A71E3135C40002FDFB /* libART.a in Frameworks */, - 5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */, + 5D7D53981F4CD74900C3E091 /* libART.a in Frameworks */, 146834051AC3E58100842450 /* libReact.a in Frameworks */, + 5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */, 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */, 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */, 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */, @@ -378,14 +413,19 @@ 3DAD3EAB1DF850E9000B6D8A /* libcxxreact.a */, 3DAD3EAD1DF850E9000B6D8A /* libjschelpers.a */, 3DAD3EAF1DF850E9000B6D8A /* libjschelpers.a */, + 5D7D53881F4CD72100C3E091 /* libthird-party.a */, + 5D7D538A1F4CD72100C3E091 /* libthird-party.a */, + 5D7D538C1F4CD72100C3E091 /* libdouble-conversion.a */, + 5D7D538E1F4CD72100C3E091 /* libdouble-conversion.a */, ); name = Products; sourceTree = ""; }; - 5D7639891E3135B90002FDFB /* Products */ = { + 5D7D53901F4CD73900C3E091 /* Products */ = { isa = PBXGroup; children = ( - 5D76398D1E3135B90002FDFB /* libART.a */, + 5D7D53951F4CD73900C3E091 /* libART.a */, + 5D7D53971F4CD73900C3E091 /* libART-tvOS.a */, ); name = Products; sourceTree = ""; @@ -394,7 +434,7 @@ isa = PBXGroup; children = ( 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */, - 5E9157351DD0AC6500FF2AA8 /* libRCTAnimation-tvOS.a */, + 5E9157351DD0AC6500FF2AA8 /* libRCTAnimation.a */, ); name = Products; sourceTree = ""; @@ -411,7 +451,7 @@ 832341AE1AAA6A7D00B99B32 /* Libraries */ = { isa = PBXGroup; children = ( - 5D7639881E3135B90002FDFB /* ART.xcodeproj */, + 5D7D538F1F4CD73900C3E091 /* ART.xcodeproj */, 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */, 146833FF1AC3E56700842450 /* React.xcodeproj */, 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */, @@ -524,8 +564,8 @@ projectDirPath = ""; projectReferences = ( { - ProductGroup = 5D7639891E3135B90002FDFB /* Products */; - ProjectRef = 5D7639881E3135B90002FDFB /* ART.xcodeproj */; + ProductGroup = 5D7D53901F4CD73900C3E091 /* Products */; + ProjectRef = 5D7D538F1F4CD73900C3E091 /* ART.xcodeproj */; }, { ProductGroup = 00C302A81ABCB8CE00DB3ED1 /* Products */; @@ -728,11 +768,46 @@ remoteRef = 3DAD3EAE1DF850E9000B6D8A /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 5D76398D1E3135B90002FDFB /* libART.a */ = { + 5D7D53881F4CD72100C3E091 /* libthird-party.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = "libthird-party.a"; + remoteRef = 5D7D53871F4CD72100C3E091 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 5D7D538A1F4CD72100C3E091 /* libthird-party.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = "libthird-party.a"; + remoteRef = 5D7D53891F4CD72100C3E091 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 5D7D538C1F4CD72100C3E091 /* libdouble-conversion.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = "libdouble-conversion.a"; + remoteRef = 5D7D538B1F4CD72100C3E091 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 5D7D538E1F4CD72100C3E091 /* libdouble-conversion.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = "libdouble-conversion.a"; + remoteRef = 5D7D538D1F4CD72100C3E091 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 5D7D53951F4CD73900C3E091 /* libART.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; path = libART.a; - remoteRef = 5D76398C1E3135B90002FDFB /* PBXContainerItemProxy */; + remoteRef = 5D7D53941F4CD73900C3E091 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 5D7D53971F4CD73900C3E091 /* libART-tvOS.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = "libART-tvOS.a"; + remoteRef = 5D7D53961F4CD73900C3E091 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */ = { @@ -742,10 +817,10 @@ remoteRef = 5E9157321DD0AC6500FF2AA8 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 5E9157351DD0AC6500FF2AA8 /* libRCTAnimation-tvOS.a */ = { + 5E9157351DD0AC6500FF2AA8 /* libRCTAnimation.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; - path = "libRCTAnimation-tvOS.a"; + path = libRCTAnimation.a; remoteRef = 5E9157341DD0AC6500FF2AA8 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -797,7 +872,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "export NODE_BINARY=node\n../node_modules/react-native/packager/react-native-xcode.sh"; + shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh"; }; /* End PBXShellScriptBuildPhase section */ @@ -853,6 +928,10 @@ INFOPLIST_FILE = ExampleTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + OTHER_LDFLAGS = ( + "-ObjC", + "-lc++", + ); PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example.app/Example"; }; @@ -866,6 +945,10 @@ INFOPLIST_FILE = ExampleTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + OTHER_LDFLAGS = ( + "-ObjC", + "-lc++", + ); PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example.app/Example"; }; diff --git a/Example/ios/Example/Info.plist b/Example/ios/Example/Info.plist index 2fb6a11..0bf27a6 100644 --- a/Example/ios/Example/Info.plist +++ b/Example/ios/Example/Info.plist @@ -4,6 +4,8 @@ CFBundleDevelopmentRegion en + CFBundleDisplayName + Example CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier diff --git a/Example/ios/ExampleTests/ExampleTests.m b/Example/ios/ExampleTests/ExampleTests.m index 857f14c..22ba225 100644 --- a/Example/ios/ExampleTests/ExampleTests.m +++ b/Example/ios/ExampleTests/ExampleTests.m @@ -37,7 +37,7 @@ - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test - (void)testRendersWelcomeScreen { - UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController]; + UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController]; NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; BOOL foundElement = NO; diff --git a/Example/package.json b/Example/package.json index 5de6c66..074b67d 100644 --- a/Example/package.json +++ b/Example/package.json @@ -7,15 +7,15 @@ "test": "jest" }, "dependencies": { - "react": "15.4.2", - "react-native": "0.40.0", + "react": "16.0.0-alpha.12", + "react-native": "0.47.2", "react-native-progress": "file:../" }, "devDependencies": { - "babel-jest": "18.0.0", - "babel-preset-react-native": "1.9.1", - "jest": "18.1.0", - "react-test-renderer": "15.4.2" + "babel-jest": "20.0.3", + "babel-preset-react-native": "3.0.1", + "jest": "20.0.4", + "react-test-renderer": "16.0.0-alpha.12" }, "jest": { "preset": "react-native" diff --git a/Pie.js b/Pie.js index c747059..21a66bd 100644 --- a/Pie.js +++ b/Pie.js @@ -1,13 +1,11 @@ -import React, { - Component, - PropTypes, -} from 'react'; - +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; import { Animated, ART, StyleSheet, View, + ViewPropTypes, } from 'react-native'; import Circle from './Shapes/Circle'; @@ -19,6 +17,8 @@ const CIRCLE = Math.PI * 2; const AnimatedSurface = Animated.createAnimatedComponent(ART.Surface); const AnimatedSector = Animated.createAnimatedComponent(Sector); +const RNViewPropTypes = ViewPropTypes || View.propTypes; + const styles = StyleSheet.create({ container: { backgroundColor: 'transparent', @@ -39,7 +39,7 @@ export class ProgressPie extends Component { ]), rotation: PropTypes.instanceOf(Animated.Value), size: PropTypes.number, - style: View.propTypes.style, + style: RNViewPropTypes.style, unfilledColor: PropTypes.string, }; diff --git a/README.md b/README.md index 307151e..d72dc6f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # react-native-progress -Progress indicators and spinners for React Native using ReactART. +Progress indicators and spinners for React Native using ReactART. ![progress-demo](https://cloud.githubusercontent.com/assets/378279/11212043/64fb1420-8d01-11e5-9ec0-5e175a837c62.gif) @@ -10,7 +10,7 @@ Progress indicators and spinners for React Native using ReactART. ### ReactART based components -To use the `Pie` or `Circle` components, you need to include the ART library in your project on iOS, for android it's already included. +To use the `Pie` or `Circle` components, you need to include the ART library in your project on iOS, for android it's already included. #### For CocoaPod users: @@ -56,9 +56,13 @@ All of the props under *Properties* in addition to the following: | Prop | Description | Default | |---|---|---| -|**`width`**|Full width of the progress bar. |`150`| +|**`width`**|Full width of the progress bar, set to `null` to use automatic flexbox sizing. |`150`| |**`height`**|Height of the progress bar. |`6`| |**`borderRadius`**|Rounding of corners, set to `0` to disable. |`4`| +|**`useNativeDriver`**|Use native driver for the animations. |`false`| +|**`animationConfig`**|Config that is passed into the `Animated` function|`{ bounciness: 0 }`| +|**`animationType`**|Animation type to animate the progress, one of: `decay`, `timing`, `spring`|`spring`| +|**`animateIncreaseOnly`**|Animate the changes to `progress` only if increasing. |`false`| ### `Progress.Circle` @@ -72,6 +76,7 @@ All of the props under *Properties* in addition to the following: |**`formatText(progress)`**|A function returning a string to be displayed for the textual representation. |*See source*| |**`textStyle`**|Styles for progress text, defaults to a same `color` as circle and `fontSize` proportional to `size` prop. |*None*| |**`direction`**|Direction of the circle `clockwise` or `counter-clockwise` |`clockwise`| +|**`strokeCap`**|Stroke Cap style for the circle `butt`, `square` or `round` |`butt`| ### `Progress.Pie` @@ -92,17 +97,18 @@ All of the props under *Properties* in addition to the following: |**`thickness`**|Thickness of the circle. |`3`| |**`duration`**|Duration of animation. |`1000`| |**`spinDuration`**|Duration of spin (orbit) animation. |`5000`| +|**`strokeCap`**|Stroke Cap style for the circle `butt`, `square` or `round` |`round`| ## Examples -* [`Example` project bundled with this module](https://github.com/oblador/react-native-progress/tree/master/Example) +* [`Example` project bundled with this module](https://github.com/oblador/react-native-progress/tree/master/Example) * [react-native-image-progress](https://github.com/oblador/react-native-image-progress) ## [Changelog](https://github.com/oblador/react-native-progress/releases) ## Thanks -To [Mandarin Drummond](https://github.com/MandarinConLaBarba) for giving me the NPM name. +To [Mandarin Drummond](https://github.com/MandarinConLaBarba) for giving me the NPM name. ## License diff --git a/Shapes/Arc.js b/Shapes/Arc.js index 72a5a00..06aeb29 100644 --- a/Shapes/Arc.js +++ b/Shapes/Arc.js @@ -1,10 +1,7 @@ /* eslint new-cap: ["error", { "capIsNew": false }] */ -import React, { - Component, - PropTypes, -} from 'react'; - +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; import { ART } from 'react-native'; const CIRCLE = Math.PI * 2; @@ -52,6 +49,7 @@ export default class Arc extends Component { top: PropTypes.number, left: PropTypes.number, }), + strokeCap: PropTypes.string, strokeWidth: PropTypes.number, direction: PropTypes.oneOf(['clockwise', 'counter-clockwise']), }; @@ -59,6 +57,7 @@ export default class Arc extends Component { static defaultProps = { startAngle: 0, offset: { top: 0, left: 0 }, + strokeCap: 'butt', strokeWidth: 0, direction: 'clockwise', }; @@ -70,6 +69,7 @@ export default class Arc extends Component { radius, offset, direction, + strokeCap, strokeWidth, ...restProps } = this.props; @@ -86,7 +86,7 @@ export default class Arc extends Component { return ( diff --git a/Shapes/Circle.js b/Shapes/Circle.js index befecb6..cc3a0c4 100644 --- a/Shapes/Circle.js +++ b/Shapes/Circle.js @@ -1,11 +1,8 @@ /* eslint new-cap: ["error", { "capIsNew": false }] */ /* eslint no-unexpected-multiline: 0 */ -import React, { - Component, - PropTypes, -} from 'react'; - +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; import { ART } from 'react-native'; function makeCirclePath(x, y, radius, direction) { diff --git a/Shapes/Sector.js b/Shapes/Sector.js index 5d6df5b..293015c 100644 --- a/Shapes/Sector.js +++ b/Shapes/Sector.js @@ -1,10 +1,7 @@ /* eslint new-cap: ["error", { "capIsNew": false }] */ -import React, { - Component, - PropTypes, -} from 'react'; - +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; import { ART } from 'react-native'; const CIRCLE = Math.PI * 2; diff --git a/package.json b/package.json index 49b760a..02ba9a6 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,8 @@ { - "name": "react-native-progress", - "version": "3.2.0", - "description": "Progress indicators and spinners for React Native using ReactART", + "name": "@ais/react-native-progress", + "version": "3.4.0", + "description": + "Progress indicators and spinners for React Native using ReactART", "main": "index.js", "scripts": { "test": "eslint *.js Shapes" @@ -34,7 +35,7 @@ }, "repository": { "type": "git", - "url": "git://github.com/oblador/react-native-progress.git" + "url": "git://github.com/AirIntServices/react-native-progress.git" }, "license": "MIT", "devDependencies": { @@ -45,5 +46,8 @@ "eslint-plugin-import": "^1.16.0", "eslint-plugin-jsx-a11y": "^2.2.3", "eslint-plugin-react": "^6.4.1" + }, + "dependencies": { + "prop-types": "^15.5.8" } } diff --git a/withAnimation.js b/withAnimation.js index 6cb756e..5db7561 100644 --- a/withAnimation.js +++ b/withAnimation.js @@ -1,8 +1,5 @@ -import React, { - Component, - PropTypes, -} from 'react'; - +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; import { Animated, Easing, @@ -24,7 +21,6 @@ export default function withAnimation(WrappedComponent, indeterminateProgress) { static defaultProps = { animated: true, - direction: 'clockwise', indeterminate: false, progress: 0, };