diff --git a/HISTORY.md b/HISTORY.md
index ceeafcb..38da95e 100644
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -2,6 +2,10 @@
---
+## 2.6.0
+
+- Refactor to hooks.
+
## 2.5.0
- Progress.Circle supports gradient color now. #73
diff --git a/README.md b/README.md
index 7520949..b268cdf 100644
--- a/README.md
+++ b/README.md
@@ -12,8 +12,10 @@ Progress Bar.
[npm-image]: http://img.shields.io/npm/v/rc-progress.svg?style=flat-square
[npm-url]: http://npmjs.org/package/rc-progress
-[travis-image]: https://img.shields.io/travis/react-component/progress.svg?style=flat-square
+[travis-image]: https://img.shields.io/travis/react-component/progress/master?style=flat-square
[travis-url]: https://travis-ci.org/react-component/progress
+[circleci-image]: https://img.shields.io/circleci/react-component/progress/master?style=flat-square
+[circleci-url]: https://circleci.com/gh/react-component/progress
[coveralls-image]: https://img.shields.io/coveralls/react-component/progress.svg?style=flat-square
[coveralls-url]: https://coveralls.io/r/react-component/progress?branch=master
[david-url]: https://david-dm.org/react-component/progress
@@ -43,15 +45,23 @@ http://react-component.github.io/progress/
## Usage
-```jsx
+```js
import { Line, Circle } from 'rc-progress';
-ReactDOM.render(
-
-
-
, container);
+export default () => (
+ <>
+
+
+ >
+);
```
+## Compatibility
+
+| [](http://godban.github.io/browsers-support-badges/)
IE / Edge | [](http://godban.github.io/browsers-support-badges/)
Firefox | [](http://godban.github.io/browsers-support-badges/)
Chrome | [](http://godban.github.io/browsers-support-badges/)
Safari | [](http://godban.github.io/browsers-support-badges/)
Electron |
+| --- | --- | --- | --- | --- |
+| IE11, Edge | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
+
## API
### props
diff --git a/package.json b/package.json
index bde0712..b80249d 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "rc-progress",
- "version": "2.5.3",
+ "version": "2.6.0",
"description": "progress ui component for react",
"keywords": [
"react",
@@ -9,7 +9,6 @@
"progress"
],
"homepage": "http://github.com/react-component/progress",
- "author": "tsjxyz@gmail.com",
"repository": {
"type": "git",
"url": "git@github.com:react-component/progress.git"
@@ -17,7 +16,7 @@
"bugs": {
"url": "http://github.com/react-component/progress/issues"
},
- "licenses": "MIT",
+ "license": "MIT",
"main": "lib/index",
"module": "es/index",
"types": "./typings/index.d.ts",
@@ -42,8 +41,8 @@
"build": "rc-tools run build",
"gh-pages": "rc-tools run gh-pages",
"start": "rc-tools run server",
- "compile": "rc-tools run compile --babel-runtime",
- "pub": "rc-tools run pub --babel-runtime",
+ "compile": "rc-tools run compile",
+ "pub": "rc-tools run pub",
"lint": "rc-tools run lint",
"lint:fix": "rc-tools run lint --fix",
"prettier": "rc-tools run prettier",
@@ -69,7 +68,6 @@
]
},
"dependencies": {
- "babel-runtime": "6.x",
- "prop-types": "^15.5.8"
+ "classnames": "^2.2.6"
}
}
diff --git a/src/Circle.js b/src/Circle.js
index 783604f..0ac2743 100644
--- a/src/Circle.js
+++ b/src/Circle.js
@@ -1,8 +1,7 @@
/* eslint react/prop-types: 0 */
-import React, { Component } from 'react';
-import PropTypes from 'prop-types';
-import enhancer from './enhancer';
-import { propTypes, defaultProps } from './types';
+import React, { useMemo } from 'react';
+import classNames from 'classnames';
+import { useTransitionDuration, defaultProps } from './common';
let gradientSeed = 0;
@@ -58,142 +57,105 @@ function getPathStyles(offset, percent, strokeColor, strokeWidth, gapDegree = 0,
};
}
-class Circle extends Component {
- paths = {};
-
- gradientId = 0;
-
- constructor() {
- super();
- this.gradientId = gradientSeed;
+const Circle = ({
+ prefixCls,
+ strokeWidth,
+ trailWidth,
+ gapDegree,
+ gapPosition,
+ trailColor,
+ strokeLinecap,
+ style,
+ className,
+ strokeColor,
+ percent,
+ ...restProps
+}) => {
+ const gradientId = useMemo(() => {
gradientSeed += 1;
- }
-
- getStokeList() {
- const {
- prefixCls,
- percent,
- strokeColor,
- strokeWidth,
- strokeLinecap,
- gapDegree,
- gapPosition,
- } = this.props;
- const percentList = toArray(percent);
- const strokeColorList = toArray(strokeColor);
-
+ return gradientSeed;
+ }, []);
+ const { pathString, pathStyle } = getPathStyles(
+ 0,
+ 100,
+ trailColor,
+ strokeWidth,
+ gapDegree,
+ gapPosition,
+ );
+ const percentList = toArray(percent);
+ const strokeColorList = toArray(strokeColor);
+ const gradient = strokeColorList.find(
+ color => Object.prototype.toString.call(color) === '[object Object]',
+ );
+
+ const [paths] = useTransitionDuration(percentList);
+
+ const getStokeList = () => {
let stackPtg = 0;
return percentList.map((ptg, index) => {
const color = strokeColorList[index] || strokeColorList[strokeColorList.length - 1];
const stroke =
Object.prototype.toString.call(color) === '[object Object]'
- ? `url(#${prefixCls}-gradient-${this.gradientId})`
+ ? `url(#${prefixCls}-gradient-${gradientId})`
: '';
- const { pathString, pathStyle } = getPathStyles(
- stackPtg,
- ptg,
- color,
- strokeWidth,
- gapDegree,
- gapPosition,
- );
-
+ const pathStyles = getPathStyles(stackPtg, ptg, color, strokeWidth, gapDegree, gapPosition);
stackPtg += ptg;
-
return (
{
- this.paths[index] = path;
- }}
+ style={pathStyles.pathStyle}
+ ref={paths[index]}
/>
);
});
- }
-
- render() {
- const {
- prefixCls,
- strokeWidth,
- trailWidth,
- gapDegree,
- gapPosition,
- trailColor,
- strokeLinecap,
- style,
- className,
- strokeColor,
- ...restProps
- } = this.props;
- const { pathString, pathStyle } = getPathStyles(
- 0,
- 100,
- trailColor,
- strokeWidth,
- gapDegree,
- gapPosition,
- );
- delete restProps.percent;
- const strokeColorList = toArray(strokeColor);
- const gradient = strokeColorList.find(
- color => Object.prototype.toString.call(color) === '[object Object]',
- );
-
- return (
-
- );
- }
-}
+ };
-Circle.propTypes = {
- ...propTypes,
- gapPosition: PropTypes.oneOf(['top', 'bottom', 'left', 'right']),
+ return (
+
+ );
};
-Circle.defaultProps = {
- ...defaultProps,
- gapPosition: 'top',
-};
+Circle.defaultProps = defaultProps;
-export default enhancer(Circle);
+export default Circle;
diff --git a/src/Line.js b/src/Line.js
index d310ddc..2a75703 100644
--- a/src/Line.js
+++ b/src/Line.js
@@ -1,89 +1,77 @@
-import React, { Component } from 'react';
-import enhancer from './enhancer';
-import { propTypes, defaultProps } from './types';
+/* eslint react/prop-types: 0 */
+import React from 'react';
+import classNames from 'classnames';
+import { useTransitionDuration, defaultProps } from './common';
-class Line extends Component {
- paths = {};
+const Line = ({
+ className,
+ percent,
+ prefixCls,
+ strokeColor,
+ strokeLinecap,
+ strokeWidth,
+ style,
+ trailColor,
+ trailWidth,
+ transition,
+ ...restProps
+}) => {
+ delete restProps.gapPosition;
+ const percentList = Array.isArray(percent) ? percent : [percent];
+ const strokeColorList = Array.isArray(strokeColor) ? strokeColor : [strokeColor];
- render() {
- const {
- className,
- percent,
- prefixCls,
- strokeColor,
- strokeLinecap,
- strokeWidth,
- style,
- trailColor,
- trailWidth,
- transition,
- ...restProps
- } = this.props;
+ const [paths] = useTransitionDuration(percentList);
- delete restProps.gapPosition;
-
- const percentList = Array.isArray(percent) ? percent : [percent];
- const strokeColorList = Array.isArray(strokeColor) ? strokeColor : [strokeColor];
-
- const center = strokeWidth / 2;
- const right = 100 - strokeWidth / 2;
- const pathString = `M ${strokeLinecap === 'round' ? center : 0},${center}
- L ${strokeLinecap === 'round' ? right : 100},${center}`;
- const viewBoxString = `0 0 100 ${strokeWidth}`;
-
- let stackPtg = 0;
-
- return (
-
- );
- }
-}
-
-Line.propTypes = propTypes;
+ const center = strokeWidth / 2;
+ const right = 100 - strokeWidth / 2;
+ const pathString = `M ${strokeLinecap === 'round' ? center : 0},${center}
+ L ${strokeLinecap === 'round' ? right : 100},${center}`;
+ const viewBoxString = `0 0 100 ${strokeWidth}`;
+ let stackPtg = 0;
+ return (
+
+ );
+};
Line.defaultProps = defaultProps;
-export default enhancer(Line);
+export default Line;
diff --git a/src/common.js b/src/common.js
new file mode 100644
index 0000000..8ac8362
--- /dev/null
+++ b/src/common.js
@@ -0,0 +1,42 @@
+import { useRef, useEffect } from 'react';
+
+export const defaultProps = {
+ className: '',
+ percent: 0,
+ prefixCls: 'rc-progress',
+ strokeColor: '#2db7f5',
+ strokeLinecap: 'round',
+ strokeWidth: 1,
+ style: {},
+ trailColor: '#D9D9D9',
+ trailWidth: 1,
+};
+
+export const useTransitionDuration = percentList => {
+ const paths = percentList.map(() => useRef());
+ const prevTimeStamp = useRef();
+ useEffect(() => {
+ const now = Date.now();
+ let updated = false;
+
+ Object.keys(paths).forEach(key => {
+ const path = paths[key].current;
+ if (!path) {
+ return;
+ }
+ updated = true;
+ const pathStyle = path.style;
+ pathStyle.transitionDuration = '.3s, .3s, .3s, .06s';
+
+ if (prevTimeStamp.current && now - prevTimeStamp.current < 100) {
+ pathStyle.transitionDuration = '0s, 0s';
+ }
+ });
+
+ if (updated) {
+ prevTimeStamp.current = Date.now();
+ }
+ });
+
+ return [paths];
+};
diff --git a/src/enhancer.js b/src/enhancer.js
deleted file mode 100644
index 97cef8b..0000000
--- a/src/enhancer.js
+++ /dev/null
@@ -1,33 +0,0 @@
-const enhancer = WrappedComponent =>
- class Progress extends WrappedComponent {
- componentDidUpdate() {
- const now = Date.now();
- let updated = false;
-
- Object.keys(this.paths).forEach(key => {
- const path = this.paths[key];
-
- if (!path) {
- return;
- }
-
- updated = true;
- const pathStyle = path.style;
- pathStyle.transitionDuration = '.3s, .3s, .3s, .06s';
-
- if (this.prevTimeStamp && now - this.prevTimeStamp < 100) {
- pathStyle.transitionDuration = '0s, 0s';
- }
- });
-
- if (updated) {
- this.prevTimeStamp = Date.now();
- }
- }
-
- render() {
- return super.render();
- }
- };
-
-export default enhancer;
diff --git a/src/types.js b/src/types.js
deleted file mode 100644
index 75297e1..0000000
--- a/src/types.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import PropTypes from 'prop-types';
-
-export const defaultProps = {
- className: '',
- percent: 0,
- prefixCls: 'rc-progress',
- strokeColor: '#2db7f5',
- strokeLinecap: 'round',
- strokeWidth: 1,
- style: {},
- trailColor: '#D9D9D9',
- trailWidth: 1,
-};
-
-const mixedType = PropTypes.oneOfType([PropTypes.number, PropTypes.string]);
-
-export const propTypes = {
- className: PropTypes.string,
- percent: PropTypes.oneOfType([mixedType, PropTypes.arrayOf(mixedType)]),
- prefixCls: PropTypes.string,
- strokeColor: PropTypes.oneOfType([
- PropTypes.string,
- PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.object])),
- PropTypes.object,
- ]),
- strokeLinecap: PropTypes.oneOf(['butt', 'round', 'square']),
- strokeWidth: mixedType,
- style: PropTypes.object,
- trailColor: PropTypes.string,
- trailWidth: mixedType,
-};
diff --git a/tests/index.spec.js b/tests/index.spec.js
index 7950839..4640e35 100644
--- a/tests/index.spec.js
+++ b/tests/index.spec.js
@@ -20,50 +20,27 @@ describe('Progress', () => {
});
describe('Line', () => {
- it('works', () => {
- const line = ReactDOM.render(, div);
- expect(line.props.percent).toBe('30');
+ it('change with animation', () => {
+ class Demo extends React.Component {
+ state = {
+ percent: '0',
+ };
+
+ render() {
+ const { percent } = this.state;
+ return ;
+ }
+ }
+ const line = ReactDOM.render(, div);
+ expect(line.state.percent).toBe('0');
+ line.setState({
+ percent: '30',
+ });
+ expect(line.state.percent).toBe('30');
});
});
describe('Circle', () => {
- it('works', () => {
- const circle = ReactDOM.render(, div);
- expect(circle.props.percent).toBe('30');
- });
-
- it('gap degree bottom', () => {
- const circle = ReactDOM.render(
- ,
- div,
- );
- expect(circle.props.percent).toBe('30');
- });
-
- it('gap degree top', () => {
- const circle = ReactDOM.render(
- ,
- div,
- );
- expect(circle.props.percent).toBe('30');
- });
-
- it('gap degree left', () => {
- const circle = ReactDOM.render(
- ,
- div,
- );
- expect(circle.props.percent).toBe('30');
- });
-
- it('gap degree right', () => {
- const circle = ReactDOM.render(
- ,
- div,
- );
- expect(circle.props.percent).toBe('30');
- });
-
it('change with animation', () => {
class Demo extends React.Component {
state = {