From 8a24f5cb702d49ee789df0effe26f6685b83ad00 Mon Sep 17 00:00:00 2001 From: lin851883537 <851883537@qq.com> Date: Thu, 3 Jun 2021 16:17:57 +0800 Subject: [PATCH 1/3] Add a more eye-catching indicator --- README.md | 6 +++ docs/examples/gap.tsx | 3 ++ docs/examples/gradient-circle.tsx | 2 + src/Circle.tsx | 84 ++++++++++++++++++++++--------- src/common.ts | 6 +-- src/interface.ts | 5 +- 6 files changed, 78 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 6e63542..2dd42b7 100644 --- a/README.md +++ b/README.md @@ -136,6 +136,12 @@ export default () => ( top the gap position, value: top, bottom, left, right. + + dot + Boolean | Object + false + within dot or not, value: true, false, { size: Number } + diff --git a/docs/examples/gap.tsx b/docs/examples/gap.tsx index 913a1ee..05e951e 100644 --- a/docs/examples/gap.tsx +++ b/docs/examples/gap.tsx @@ -30,6 +30,7 @@ class Example extends React.Component { const circleContainerStyle = { width: '200px', height: '200px', + marginBottom: '60px' }; const { percent, colorIndex } = this.state; const color = getColor(colorIndex); @@ -48,6 +49,7 @@ class Example extends React.Component { strokeWidth={6} strokeLinecap="square" strokeColor={color} + dot={{ size: 10 }} />
@@ -59,6 +61,7 @@ class Example extends React.Component { trailWidth={6} strokeLinecap="round" strokeColor={[color, getColor(colorIndex + 1), getColor(colorIndex + 2)]} + dot={true} />
diff --git a/docs/examples/gradient-circle.tsx b/docs/examples/gradient-circle.tsx index 58762d0..52abeb5 100644 --- a/docs/examples/gradient-circle.tsx +++ b/docs/examples/gradient-circle.tsx @@ -20,6 +20,7 @@ const Example = () => { '0%': '#108ee9', '100%': '#87d068', }} + dot={true} />

Circle Progress {100}%

@@ -47,6 +48,7 @@ const Example = () => { '0%': '#87d068', }, ]} + dot={{}} /> diff --git a/src/Circle.tsx b/src/Circle.tsx index b2772f6..96016c3 100644 --- a/src/Circle.tsx +++ b/src/Circle.tsx @@ -5,6 +5,10 @@ import type { ProgressProps, GapPositionType } from './interface'; let gradientSeed = 0; +function pxToNumber(px: string) { + return parseInt(px.slice(0, px.indexOf('p')), 10); +} + function stripPercentToNumber(percent: string) { return +percent.replace('%', ''); } @@ -76,6 +80,7 @@ const Circle: React.FC = ({ className, strokeColor, percent, + dot, ...restProps }) => { const gradientId = React.useMemo(() => { @@ -98,31 +103,62 @@ const Circle: React.FC = ({ const [paths] = useTransitionDuration(percentList); + const getDotList = (pathDoms) => { + const path = document.createElementNS('http://www.w3.org/2000/svg', 'path'); + if (dot) { + return pathDoms.map((pathDom, index) => { + const strokeDasharrayTemp = pathDom.props.style.strokeDasharray; + const strokeLength = + pxToNumber(strokeDasharrayTemp.slice(0, strokeDasharrayTemp.indexOf(' '))) + + Math.abs(pxToNumber(pathDom.props.style.strokeDashoffset)) + + strokeWidth / 2; + + path.setAttribute('d', pathDom.props.d); + const dotPoint = path.getPointAtLength(strokeLength); + return ( + + ); + }); + } + return []; + + }; + 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-${gradientId})` - : ''; - const pathStyles = getPathStyles(stackPtg, ptg, color, strokeWidth, gapDegree, gapPosition); - stackPtg += ptg; - return ( - - ); - }); + const pathDoms = percentList + .map((ptg, index) => { + const color = strokeColorList[index] || strokeColorList[strokeColorList.length - 1]; + const stroke = + Object.prototype.toString.call(color) === '[object Object]' + ? `url(#${prefixCls}-gradient-${gradientId})` + : ''; + const pathStyles = getPathStyles(stackPtg, ptg, color, strokeWidth, gapDegree, gapPosition); + stackPtg += ptg; + return ( + + ); + }) + .reverse(); + return pathDoms.concat(getDotList(pathDoms)); }; return ( @@ -158,7 +194,7 @@ const Circle: React.FC = ({ fillOpacity="0" style={pathStyle} /> - {getStokeList().reverse()} + {getStokeList()} ); }; diff --git a/src/common.ts b/src/common.ts index 4b7e6fe..54df6de 100644 --- a/src/common.ts +++ b/src/common.ts @@ -1,5 +1,5 @@ import { useRef, useEffect } from 'react'; -import { ProgressProps } from './interface'; +import type { ProgressProps } from './interface'; export const defaultProps: Partial = { className: '', @@ -8,7 +8,7 @@ export const defaultProps: Partial = { strokeColor: '#2db7f5', strokeLinecap: 'round', strokeWidth: 1, - style: {}, + style: { overflow: 'visible' }, trailColor: '#D9D9D9', trailWidth: 1, }; @@ -21,7 +21,7 @@ export const useTransitionDuration = (percentList: number[]) => { const now = Date.now(); let updated = false; - Object.keys(paths).forEach(key => { + Object.keys(paths).forEach((key) => { const path = paths[key].current; if (!path) { return; diff --git a/src/interface.ts b/src/interface.ts index 8599290..7356bd0 100644 --- a/src/interface.ts +++ b/src/interface.ts @@ -1,4 +1,4 @@ -import * as React from 'react'; +import type * as React from 'react'; export interface ProgressProps { strokeWidth?: number; @@ -13,6 +13,7 @@ export interface ProgressProps { gapDegree?: number; gapPosition?: GapPositionType; transition?: string; + dot?: dotType; } export type StrokeColorType = string | string[] | object; @@ -20,3 +21,5 @@ export type StrokeColorType = string | string[] | object; export type GapPositionType = 'top' | 'right' | 'bottom' | 'left'; export type StrokeLinecapType = 'round' | 'butt' | 'square'; + +export type dotType = boolean | object; From 342a009ea64857095c20950dc130a936a52ca5aa Mon Sep 17 00:00:00 2001 From: lin851883537 <851883537@qq.com> Date: Thu, 3 Jun 2021 18:03:54 +0800 Subject: [PATCH 2/3] update DotType --- docs/examples/gap.tsx | 2 ++ docs/examples/gradient-circle.tsx | 4 ++-- src/Circle.tsx | 5 ++--- src/interface.ts | 4 ++-- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/examples/gap.tsx b/docs/examples/gap.tsx index 05e951e..f12a50b 100644 --- a/docs/examples/gap.tsx +++ b/docs/examples/gap.tsx @@ -73,6 +73,7 @@ class Example extends React.Component { strokeWidth={6} strokeLinecap="square" strokeColor={color} + dot={{ size: 'p' }} />
@@ -83,6 +84,7 @@ class Example extends React.Component { strokeWidth={6} strokeLinecap="square" strokeColor={color} + dot={{ size: [] }} />
diff --git a/docs/examples/gradient-circle.tsx b/docs/examples/gradient-circle.tsx index 52abeb5..b97d161 100644 --- a/docs/examples/gradient-circle.tsx +++ b/docs/examples/gradient-circle.tsx @@ -20,7 +20,7 @@ const Example = () => { '0%': '#108ee9', '100%': '#87d068', }} - dot={true} + dot={{ size: '10' }} />

Circle Progress {100}%

@@ -33,6 +33,7 @@ const Example = () => { '100%': '#108ee9', '0%': '#87d068', }} + dot={{}} />

Circle With Success Percent {65}%

@@ -48,7 +49,6 @@ const Example = () => { '0%': '#87d068', }, ]} - dot={{}} /> diff --git a/src/Circle.tsx b/src/Circle.tsx index 96016c3..831a248 100644 --- a/src/Circle.tsx +++ b/src/Circle.tsx @@ -126,9 +126,8 @@ const Circle: React.FC = ({ /> ); }); - } - return []; - + } + return []; }; const getStokeList = () => { diff --git a/src/interface.ts b/src/interface.ts index 7356bd0..f841c11 100644 --- a/src/interface.ts +++ b/src/interface.ts @@ -13,7 +13,7 @@ export interface ProgressProps { gapDegree?: number; gapPosition?: GapPositionType; transition?: string; - dot?: dotType; + dot?: DotType; } export type StrokeColorType = string | string[] | object; @@ -22,4 +22,4 @@ export type GapPositionType = 'top' | 'right' | 'bottom' | 'left'; export type StrokeLinecapType = 'round' | 'butt' | 'square'; -export type dotType = boolean | object; +export type DotType = boolean | { size: number }; From cd551c0a9c4bfce1944eb21e1454a88ea6f09bf8 Mon Sep 17 00:00:00 2001 From: lin851883537 <851883537@qq.com> Date: Fri, 4 Jun 2021 15:02:23 +0800 Subject: [PATCH 3/3] update test cases of dot and snap of jest --- README.md | 2 +- docs/examples/gap.tsx | 4 +- docs/examples/gradient-circle.tsx | 5 +- src/Circle.tsx | 7 ++- tests/__snapshots__/index.spec.js.snap | 72 +++++++++++++++++++++----- tests/index.spec.js | 26 ++++++++++ 6 files changed, 97 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 2dd42b7..f430d6d 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,7 @@ export default () => ( dot Boolean | Object false - within dot or not, value: true, false, { size: Number } + within dot or not, value: true, false, { size: Number }, if the size is not a number, it will be the strokeWidth as default diff --git a/docs/examples/gap.tsx b/docs/examples/gap.tsx index f12a50b..b358b61 100644 --- a/docs/examples/gap.tsx +++ b/docs/examples/gap.tsx @@ -41,6 +41,7 @@ class Example extends React.Component { Change State [{percent}]

+

within dot

{ />
+

without dot

{ strokeWidth={6} strokeLinecap="square" strokeColor={color} - dot={{ size: 'p' }} />
@@ -84,7 +85,6 @@ class Example extends React.Component { strokeWidth={6} strokeLinecap="square" strokeColor={color} - dot={{ size: [] }} />
diff --git a/docs/examples/gradient-circle.tsx b/docs/examples/gradient-circle.tsx index b97d161..c4200f7 100644 --- a/docs/examples/gradient-circle.tsx +++ b/docs/examples/gradient-circle.tsx @@ -10,7 +10,7 @@ const Example = () => { return (
-

Circle Progress {90}%

+

Circle Progress {90}% (within dot)

{ '0%': '#108ee9', '100%': '#87d068', }} - dot={{ size: '10' }} + dot={true} />

Circle Progress {100}%

@@ -33,7 +33,6 @@ const Example = () => { '100%': '#108ee9', '0%': '#87d068', }} - dot={{}} />

Circle With Success Percent {65}%

diff --git a/src/Circle.tsx b/src/Circle.tsx index 831a248..8627a42 100644 --- a/src/Circle.tsx +++ b/src/Circle.tsx @@ -115,13 +115,18 @@ const Circle: React.FC = ({ path.setAttribute('d', pathDom.props.d); const dotPoint = path.getPointAtLength(strokeLength); + return ( ); diff --git a/tests/__snapshots__/index.spec.js.snap b/tests/__snapshots__/index.spec.js.snap index a69bdb6..616791f 100644 --- a/tests/__snapshots__/index.spec.js.snap +++ b/tests/__snapshots__/index.spec.js.snap @@ -153,13 +153,21 @@ Array [ strokeColor="#2db7f5" strokeLinecap="square" strokeWidth="6" - style={Object {}} + style={ + Object { + "overflow": "visible", + } + } trailColor="#D9D9D9" trailWidth={1} > { ); }); }); + + describe('dot', () => { + it('the size of dot must be a number', () => { + const wrapper = mount( + , + ); + expect(wrapper.find('.rc-progress-circle-dot').getDOMNode().r).toBe('6'); + + wrapper.setProps({ dot: { size: 10 } }); + expect(wrapper.find('.rc-progress-circle-dot').getDOMNode().r).toBe('10'); + + wrapper.setProps({ dot: true }); + expect(wrapper.find('.rc-progress-circle-dot').getDOMNode().r).toBe('6'); + + wrapper.setProps({ dot: [] }); + expect(wrapper.find('.rc-progress-circle-dot').getDOMNode().r).toBe('6'); + }); + }); });