diff --git a/examples/gradient-circle.js b/examples/gradient-circle.js index bbf7cef..9acefee 100644 --- a/examples/gradient-circle.js +++ b/examples/gradient-circle.js @@ -30,11 +30,26 @@ const Example = () => { strokeWidth="6" strokeLinecap="round" strokeColor={{ - '100%': '#87d068', - '0%': '#108ee9', + '100%': '#108ee9', + '0%': '#87d068', }} /> +

Circle With Success Percent {65}%

+
+ +
); }; diff --git a/src/Circle.js b/src/Circle.js index f3b446d..582b2b4 100644 --- a/src/Circle.js +++ b/src/Circle.js @@ -4,6 +4,16 @@ import PropTypes from 'prop-types'; import enhancer from './enhancer'; import { propTypes, defaultProps } from './types'; +let gradientSeed = 0; + +function stripPercentToNumber(percent) { + return +percent.replace('%', ''); +} + +function toArray(symArray) { + return Array.isArray(symArray) ? symArray : [symArray]; +} + function getPathStyles(offset, percent, strokeColor, strokeWidth, gapDegree = 0, gapPosition) { const radius = 50 - strokeWidth / 2; let beginPositionX = 0; @@ -51,6 +61,14 @@ function getPathStyles(offset, percent, strokeColor, strokeWidth, gapDegree = 0, class Circle extends Component { paths = {}; + gradientId = 0; + + constructor() { + super(); + this.gradientId = gradientSeed; + gradientSeed += 1; + } + getStokeList() { const { prefixCls, @@ -61,15 +79,16 @@ class Circle extends Component { gapDegree, gapPosition, } = this.props; - const percentList = Array.isArray(percent) ? percent : [percent]; - const strokeColorList = Array.isArray(strokeColor) ? strokeColor : [strokeColor]; - - const stroke = - Object.prototype.toString.call(strokeColor) === '[object Object]' ? 'url(#gradient)' : ''; + const percentList = toArray(percent); + const strokeColorList = toArray(strokeColor); 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})` + : ''; const { pathString, pathStyle } = getPathStyles( stackPtg, ptg, @@ -122,7 +141,11 @@ class Circle extends Component { gapPosition, ); delete restProps.percent; - const isGradient = Object.prototype.toString.call(strokeColor) === '[object Object]'; + const strokeColorList = toArray(strokeColor); + const gradient = strokeColorList.find( + color => Object.prototype.toString.call(color) === '[object Object]', + ); + return ( - {isGradient && ( + {gradient && ( - - {Object.keys(strokeColor).map((key, index) => ( - - ))} + + {Object.keys(gradient) + .sort((a, b) => stripPercentToNumber(a) - stripPercentToNumber(b)) + .map((key, index) => ( + + ))} )} diff --git a/src/types.js b/src/types.js index 0b5ac5e..75297e1 100644 --- a/src/types.js +++ b/src/types.js @@ -20,7 +20,7 @@ export const propTypes = { prefixCls: PropTypes.string, strokeColor: PropTypes.oneOfType([ PropTypes.string, - PropTypes.arrayOf(PropTypes.string), + PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.object])), PropTypes.object, ]), strokeLinecap: PropTypes.oneOf(['butt', 'round', 'square']), diff --git a/tests/index.spec.js b/tests/index.spec.js index 7d97269..7950839 100644 --- a/tests/index.spec.js +++ b/tests/index.spec.js @@ -3,6 +3,10 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { Line, Circle } from '../src'; +function getGradientIdFromDef(def) { + return def.firstElementChild.attributes.getNamedItem('id').value; +} + describe('Progress', () => { let div = null; beforeEach(() => { @@ -79,19 +83,38 @@ describe('Progress', () => { expect(circle.state.percent).toBe('30'); }); - it('circle support gradient color', () => { - const circle = ReactDOM.render( - - , div); - expect(circle.props.percent).toBe(90); - }) + it('should gradient works and circles have different gradient IDs', () => { + ReactDOM.render( + <> + + + , + div, + ); + + const gradientDefs = div.querySelectorAll('defs'); + const idFirst = getGradientIdFromDef(gradientDefs[0]); + const idSecond = getGradientIdFromDef(gradientDefs[1]); + const idRE = /^rc-progress-gradient-\d{1,}$/; + expect(idFirst).toMatch(idRE); + expect(idSecond).toMatch(idRE); + expect(idFirst === idSecond).toBeFalsy(); + }); }); });