feat: V5 Responsive Circle Progress (#38231)

* feat: V5 Responsive Circle Progress

* fix: add useMemo

* Update components/progress/demo/circle-micro.md

Co-authored-by: MadCcc <1075746765@qq.com>

* Update components/progress/demo/circle-micro.md

Co-authored-by: MadCcc <1075746765@qq.com>

* Update components/progress/demo/circle-micro.md

Co-authored-by: MadCcc <1075746765@qq.com>

* Update components/progress/progress.tsx

Co-authored-by: MadCcc <1075746765@qq.com>

* fix: raname processInfo

* fix: add dep list

* fix: add demo

* fix: fix width

* fix: fix width

* fix: fix snap

* fix: rename

* fix: snap

* Update components/progress/Circle.tsx

Co-authored-by: MadCcc <1075746765@qq.com>

* fix: rename

* fix: fix style

* fix: update demo

* fix: fix style

* fix: fix ci

* fix: fix style

* fix: del verticalAlign

* fix: fix

* fix: fix cicd

* fix: update demo

* fix: update demo

* fix: fix style

* fix: fix style

Co-authored-by: MadCcc <1075746765@qq.com>
This commit is contained in:
lijianan 2022-10-31 10:23:26 +08:00 committed by GitHub
parent 752d671acb
commit 4ca2ed63bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 483 additions and 261 deletions

View File

@ -1,36 +1,27 @@
import { presetPrimaryColors } from '@ant-design/colors';
import classNames from 'classnames';
import { Circle as RCCircle } from 'rc-progress';
import * as React from 'react';
import Tooltip from '../tooltip';
import type { ProgressGradient, ProgressProps } from './progress';
import { getSuccessPercent, validProgress } from './utils';
import { getPercentage, getStrokeColor } from './utils';
interface CircleProps extends ProgressProps {
const CIRCLE_MIN_STROKE_WIDTH = 3;
const getMinPercent = (width: number): number => (CIRCLE_MIN_STROKE_WIDTH / width) * 100;
export interface CircleProps extends ProgressProps {
prefixCls: string;
children: React.ReactNode;
progressStatus: string;
strokeColor?: string | ProgressGradient;
}
function getPercentage({ percent, success, successPercent }: CircleProps) {
const realSuccessPercent = validProgress(getSuccessPercent({ success, successPercent }));
return [realSuccessPercent, validProgress(validProgress(percent) - realSuccessPercent)];
}
function getStrokeColor({
success = {},
strokeColor,
}: Partial<CircleProps>): (string | Record<string, string>)[] {
const { strokeColor: successColor } = success;
return [successColor || presetPrimaryColors.green, strokeColor || null!];
}
const Circle: React.FC<CircleProps> = props => {
const {
prefixCls,
width,
strokeWidth,
trailColor = null as any,
trailColor = null as unknown as string,
strokeLinecap = 'round',
gapPosition,
gapDegree,
@ -38,16 +29,26 @@ const Circle: React.FC<CircleProps> = props => {
children,
success,
} = props;
const circleSize = width || 120;
const circleStyle = {
const circleStyle: React.CSSProperties = {
width: circleSize,
height: circleSize,
fontSize: circleSize * 0.15 + 6,
} as React.CSSProperties;
const circleWidth = strokeWidth || 6;
const gapPos = gapPosition || (type === 'dashboard' && 'bottom') || undefined;
};
const getGapDegree = () => {
const memoizedStrokeWidth = React.useMemo<number>(() => {
if (!strokeWidth) {
return Math.max(getMinPercent(circleSize), 6);
}
if (strokeWidth * 0.01 * circleSize <= CIRCLE_MIN_STROKE_WIDTH) {
return getMinPercent(circleSize);
}
return strokeWidth;
}, [circleSize, strokeWidth]);
const getGapDegree = React.useMemo<number | undefined>(() => {
// Support gapDeg = 0 when type = 'dashboard'
if (gapDegree || gapDegree === 0) {
return gapDegree;
@ -56,7 +57,9 @@ const Circle: React.FC<CircleProps> = props => {
return 75;
}
return undefined;
};
}, [gapDegree, type]);
const gapPos = gapPosition || (type === 'dashboard' && 'bottom') || undefined;
// using className to style stroke color
const isGradient = Object.prototype.toString.call(props.strokeColor) === '[object Object]';
@ -66,20 +69,30 @@ const Circle: React.FC<CircleProps> = props => {
[`${prefixCls}-circle-gradient`]: isGradient,
});
const circleContent = (
<RCCircle
percent={getPercentage(props)}
strokeWidth={memoizedStrokeWidth}
trailWidth={memoizedStrokeWidth}
strokeColor={strokeColor}
strokeLinecap={strokeLinecap}
trailColor={trailColor}
prefixCls={prefixCls}
gapDegree={getGapDegree}
gapPosition={gapPos}
/>
);
return (
<div className={wrapperClassName} style={circleStyle}>
<RCCircle
percent={getPercentage(props)}
strokeWidth={circleWidth}
trailWidth={circleWidth}
strokeColor={strokeColor}
strokeLinecap={strokeLinecap}
trailColor={trailColor}
prefixCls={prefixCls}
gapDegree={getGapDegree()}
gapPosition={gapPos}
/>
{children}
{circleSize <= 20 ? (
<Tooltip title={children}>{circleContent}</Tooltip>
) : (
<>
{circleContent}
{children}
</>
)}
</div>
);
};

View File

@ -49,7 +49,10 @@ export const sortGradient = (gradients: StringGradients) => {
* "100%": "#ffffff"
* }
*/
export const handleGradient = (strokeColor: ProgressGradient, directionConfig?: DirectionType) => {
export const handleGradient = (
strokeColor: ProgressGradient,
directionConfig?: DirectionType,
): React.CSSProperties => {
const {
from = presetPrimaryColors.blue,
to = presetPrimaryColors.blue,
@ -77,20 +80,19 @@ const Line: React.FC<LineProps> = props => {
success,
} = props;
const backgroundProps =
const backgroundProps: React.CSSProperties =
strokeColor && typeof strokeColor !== 'string'
? handleGradient(strokeColor, directionConfig)
: {
background: strokeColor,
};
: { backgroundColor: strokeColor };
const borderRadius = strokeLinecap === 'square' || strokeLinecap === 'butt' ? 0 : undefined;
const trailStyle = {
const trailStyle: React.CSSProperties = {
backgroundColor: trailColor || undefined,
borderRadius,
};
const percentStyle = {
const percentStyle: React.CSSProperties = {
width: `${validProgress(percent)}%`,
height: strokeWidth || (size === 'small' ? 6 : 8),
borderRadius,
@ -99,24 +101,21 @@ const Line: React.FC<LineProps> = props => {
const successPercent = getSuccessPercent(props);
const successPercentStyle = {
const successPercentStyle: React.CSSProperties = {
width: `${validProgress(successPercent)}%`,
height: strokeWidth || (size === 'small' ? 6 : 8),
borderRadius,
backgroundColor: success?.strokeColor,
};
const successSegment =
successPercent !== undefined ? (
<div className={`${prefixCls}-success-bg`} style={successPercentStyle} />
) : null;
return (
<>
<div className={`${prefixCls}-outer`}>
<div className={`${prefixCls}-inner`} style={trailStyle}>
<div className={`${prefixCls}-bg`} style={percentStyle} />
{successSegment}
{successPercent !== undefined ? (
<div className={`${prefixCls}-success-bg`} style={successPercentStyle} />
) : null}
</div>
</div>
{children}

View File

@ -4,6 +4,7 @@ exports[`renders ./components/progress/demo/circle.md extend context correctly 1
Array [
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
style="margin-right:8px"
>
<div
class="ant-progress-inner"
@ -119,6 +120,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-success ant-progress-show-info ant-progress-default"
style="margin-left:8px"
>
<div
class="ant-progress-inner"
@ -190,6 +192,7 @@ exports[`renders ./components/progress/demo/circle-dynamic.md extend context cor
Array [
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
style="margin-right:8px"
>
<div
class="ant-progress-inner"
@ -298,10 +301,94 @@ Array [
]
`;
exports[`renders ./components/progress/demo/circle-micro.md extend context correctly 1`] = `
Array [
<div
class="ant-progress ant-progress-inline-circle ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
>
<div
class="ant-progress-inner"
style="width:14px;height:14px;font-size:8.1px"
>
<svg
class="ant-progress-circle"
viewBox="0 0 100 100"
>
<circle
class="ant-progress-circle-trail"
cx="50"
cy="50"
r="39.285714285714285"
stroke="#e6f4ff"
stroke-linecap="round"
stroke-width="21.428571428571427"
style="stroke:#e6f4ff;stroke-dasharray:246.83942278205518px 246.83942278205518;stroke-dashoffset:0;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
<circle
class="ant-progress-circle-path"
cx="50"
cy="50"
opacity="1"
r="39.285714285714285"
stroke-linecap="round"
stroke-width="21.428571428571427"
style="stroke-dasharray:246.83942278205518px 246.83942278205518;stroke-dashoffset:109.45005482710779;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
<circle
class="ant-progress-circle-path"
cx="50"
cy="50"
opacity="0"
r="39.285714285714285"
stroke-linecap="round"
stroke-width="21.428571428571427"
style="stroke:#52C41A;stroke-dasharray:246.83942278205518px 246.83942278205518;stroke-dashoffset:246.8294227820552;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
</svg>
<div>
<div
class="ant-tooltip"
style="opacity:0"
>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-arrow"
>
<span
class="ant-tooltip-arrow-content"
/>
</div>
<div
class="ant-tooltip-inner"
role="tooltip"
>
<span
class="ant-progress-text"
title="进行中已完成60%"
>
进行中已完成60%
</span>
</div>
</div>
</div>
</div>
</div>
</div>,
<span
style="margin-left:8px"
>
代码发布
</span>,
]
`;
exports[`renders ./components/progress/demo/circle-mini.md extend context correctly 1`] = `
Array [
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
style="margin-right:8px"
>
<div
class="ant-progress-inner"
@ -417,6 +504,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-success ant-progress-show-info ant-progress-default"
style="margin-left:8px"
>
<div
class="ant-progress-inner"
@ -488,6 +576,7 @@ exports[`renders ./components/progress/demo/dashboard.md extend context correctl
Array [
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
style="margin-right:8px"
>
<div
class="ant-progress-inner"
@ -725,6 +814,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-success ant-progress-show-info ant-progress-default"
style="margin-left:8px"
>
<div
class="ant-progress-inner"
@ -891,6 +981,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-success ant-progress-show-info ant-progress-default"
style="margin-left:8px"
>
<div
class="ant-progress-inner ant-progress-circle-gradient"
@ -1325,6 +1416,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
style="margin-left:8px"
>
<div
class="ant-progress-inner"
@ -1502,6 +1594,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
style="margin-left:8px"
>
<div
class="ant-progress-inner"

View File

@ -4,6 +4,7 @@ exports[`renders ./components/progress/demo/circle.md correctly 1`] = `
Array [
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
style="margin-right:8px"
>
<div
class="ant-progress-inner"
@ -119,6 +120,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-success ant-progress-show-info ant-progress-default"
style="margin-left:8px"
>
<div
class="ant-progress-inner"
@ -190,6 +192,7 @@ exports[`renders ./components/progress/demo/circle-dynamic.md correctly 1`] = `
Array [
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
style="margin-right:8px"
>
<div
class="ant-progress-inner"
@ -298,10 +301,65 @@ Array [
]
`;
exports[`renders ./components/progress/demo/circle-micro.md correctly 1`] = `
Array [
<div
class="ant-progress ant-progress-inline-circle ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
>
<div
class="ant-progress-inner"
style="width:14px;height:14px;font-size:8.1px"
>
<svg
class="ant-progress-circle"
viewBox="0 0 100 100"
>
<circle
class="ant-progress-circle-trail"
cx="50"
cy="50"
r="39.285714285714285"
stroke="#e6f4ff"
stroke-linecap="round"
stroke-width="21.428571428571427"
style="stroke:#e6f4ff;stroke-dasharray:246.83942278205518px 246.83942278205518;stroke-dashoffset:0;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
<circle
class="ant-progress-circle-path"
cx="50"
cy="50"
opacity="1"
r="39.285714285714285"
stroke-linecap="round"
stroke-width="21.428571428571427"
style="stroke-dasharray:246.83942278205518px 246.83942278205518;stroke-dashoffset:109.45005482710779;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
<circle
class="ant-progress-circle-path"
cx="50"
cy="50"
opacity="0"
r="39.285714285714285"
stroke-linecap="round"
stroke-width="21.428571428571427"
style="stroke:#52C41A;stroke-dasharray:246.83942278205518px 246.83942278205518;stroke-dashoffset:246.8294227820552;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
</svg>
</div>
</div>,
<span
style="margin-left:8px"
>
代码发布
</span>,
]
`;
exports[`renders ./components/progress/demo/circle-mini.md correctly 1`] = `
Array [
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
style="margin-right:8px"
>
<div
class="ant-progress-inner"
@ -417,6 +475,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-success ant-progress-show-info ant-progress-default"
style="margin-left:8px"
>
<div
class="ant-progress-inner"
@ -488,6 +547,7 @@ exports[`renders ./components/progress/demo/dashboard.md correctly 1`] = `
Array [
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
style="margin-right:8px"
>
<div
class="ant-progress-inner"
@ -725,6 +785,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-success ant-progress-show-info ant-progress-default"
style="margin-left:8px"
>
<div
class="ant-progress-inner"
@ -891,6 +952,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-success ant-progress-show-info ant-progress-default"
style="margin-left:8px"
>
<div
class="ant-progress-inner ant-progress-circle-gradient"
@ -1325,6 +1387,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
style="margin-left:8px"
>
<div
class="ant-progress-inner"
@ -1454,6 +1517,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
style="margin-left:8px"
>
<div
class="ant-progress-inner"

View File

@ -450,6 +450,60 @@ exports[`Progress render strokeColor 3`] = `
</div>
`;
exports[`Progress render strokeWidth of progress 1`] = `
<div>
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
>
<div
class="ant-progress-inner"
style="width: 120px; height: 120px; font-size: 24px;"
>
<svg
class="ant-progress-circle"
viewBox="0 0 100 100"
>
<circle
class="ant-progress-circle-trail"
cx="50"
cy="50"
r="25"
stroke-linecap="round"
stroke-width="50"
style="stroke-dasharray: 157.07963267948966px 157.07963267948966; stroke-dashoffset: 0; transform: rotate(-90deg); transform-origin: 50% 50%; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s; fill-opacity: 0;"
/>
<circle
class="ant-progress-circle-path"
cx="50"
cy="50"
opacity="1"
r="25"
stroke-linecap="round"
stroke-width="50"
style="stroke-dasharray: 157.07963267948966px 157.07963267948966; stroke-dashoffset: 134.95574287564276; transform: rotate(-90deg); transform-origin: 50% 50%; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s; fill-opacity: 0; transition-duration: 0s, 0s;"
/>
<circle
class="ant-progress-circle-path"
cx="50"
cy="50"
opacity="0"
r="25"
stroke-linecap="round"
stroke-width="50"
style="stroke: #52C41A; stroke-dasharray: 157.07963267948966px 157.07963267948966; stroke-dashoffset: 157.06963267948967; transform: rotate(-90deg); transform-origin: 50% 50%; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s; fill-opacity: 0; transition-duration: 0s, 0s;"
/>
</svg>
<span
class="ant-progress-text"
title="30%"
>
30%
</span>
</div>
</div>
</div>
`;
exports[`Progress render successColor progress 1`] = `
<div
class="ant-progress ant-progress-line ant-progress-status-normal ant-progress-show-info ant-progress-default"

View File

@ -29,6 +29,11 @@ describe('Progress', () => {
expect(wrapper.firstChild).toMatchSnapshot();
});
it('render strokeWidth of progress', () => {
const { container } = render(<Progress type="circle" percent={30} strokeWidth={50} />);
expect(container).toMatchSnapshot();
});
it('render out-of-range progress with info', () => {
const { container: wrapper } = render(<Progress percent={120} showInfo />);
expect(wrapper.firstChild).toMatchSnapshot();

View File

@ -39,7 +39,7 @@ const App: React.FC = () => {
return (
<>
<Progress type="circle" percent={percent} />
<Progress type="circle" percent={percent} style={{ marginRight: 8 }} />
<Button.Group>
<Button onClick={decline} icon={<MinusOutlined />} />
<Button onClick={increase} icon={<PlusOutlined />} />

View File

@ -0,0 +1,35 @@
---
order: 3
title:
zh-CN: 响应式进度圈
en-US: Responsive circular progress bar
---
## zh-CN
响应式的圈形进度,当 `width` 小于等于 20 的时候,进度信息将不会显示在进度圈里面,而是以 Tooltip 的形式显示。
## en-US
Responsive circular progress bar. When `width` is smaller than 20, progress information will be displayed in Tooltip.
```tsx
import { Progress } from 'antd';
import React from 'react';
const App: React.FC = () => (
<>
<Progress
type="circle"
trailColor="#e6f4ff"
percent={60}
strokeWidth={20}
width={14}
format={number => `进行中,已完成${number}%`}
/>
<span style={{ marginLeft: 8 }}>代码发布</span>
</>
);
export default App;
```

View File

@ -19,9 +19,9 @@ import React from 'react';
const App: React.FC = () => (
<>
<Progress type="circle" percent={30} width={80} />
<Progress type="circle" percent={30} width={80} style={{ marginRight: 8 }} />
<Progress type="circle" percent={70} width={80} status="exception" />
<Progress type="circle" percent={100} width={80} />
<Progress type="circle" percent={100} width={80} style={{ marginLeft: 8 }} />
</>
);

View File

@ -19,19 +19,11 @@ import React from 'react';
const App: React.FC = () => (
<>
<Progress type="circle" percent={75} />
<Progress type="circle" percent={75} style={{ marginRight: 8 }} />
<Progress type="circle" percent={70} status="exception" />
<Progress type="circle" percent={100} />
<Progress type="circle" percent={100} style={{ marginLeft: 8 }} />
</>
);
export default App;
```
<style>
.ant-progress-circle-wrap,
.ant-progress-line-wrap {
margin-right: 8px;
margin-bottom: 5px;
}
</style>

View File

@ -19,7 +19,7 @@ import React from 'react';
const App: React.FC = () => (
<>
<Progress type="dashboard" percent={75} />
<Progress type="dashboard" percent={75} style={{ marginRight: 8 }} />
<Progress type="dashboard" percent={75} gapDegree={30} />
</>
);

View File

@ -20,22 +20,9 @@ import React from 'react';
const App: React.FC = () => (
<>
<Progress type="circle" percent={75} format={percent => `${percent} Days`} />
<Progress type="circle" percent={100} format={() => 'Done'} />
<Progress type="circle" percent={100} format={() => 'Done'} style={{ marginLeft: 8 }} />
</>
);
export default App;
```
<style>
div.ant-progress-circle,
div.ant-progress-line {
margin-right: 8px;
margin-bottom: 8px;
}
[class*='-col-rtl'] div.ant-progress-circle,
[class*='-col-rtl'] div.ant-progress-line {
margin-right: 0;
margin-left: 8px;
}
</style>

View File

@ -19,36 +19,14 @@ import React from 'react';
const App: React.FC = () => (
<>
<Progress
strokeColor={{
'0%': '#108ee9',
'100%': '#87d068',
}}
percent={99.9}
/>
<Progress
strokeColor={{
from: '#108ee9',
to: '#87d068',
}}
percent={99.9}
status="active"
/>
<Progress percent={99.9} strokeColor={{ '0%': '#108ee9', '100%': '#87d068' }} />
<Progress percent={99.9} status="active" strokeColor={{ from: '#108ee9', to: '#87d068' }} />
<Progress type="circle" percent={90} strokeColor={{ '0%': '#108ee9', '100%': '#87d068' }} />
<Progress
type="circle"
strokeColor={{
'0%': '#108ee9',
'100%': '#87d068',
}}
percent={90}
/>
<Progress
type="circle"
strokeColor={{
'0%': '#108ee9',
'100%': '#87d068',
}}
percent={100}
style={{ marginLeft: 8 }}
strokeColor={{ '0%': '#108ee9', '100%': '#87d068' }}
/>
</>
);

View File

@ -21,7 +21,7 @@ const App: React.FC = () => (
<>
<Progress strokeLinecap="butt" percent={75} />
<Progress strokeLinecap="butt" type="circle" percent={75} />
<Progress strokeLinecap="butt" type="dashboard" percent={75} />
<Progress strokeLinecap="butt" type="dashboard" percent={75} style={{ marginLeft: 8 }} />
</>
);

View File

@ -22,13 +22,11 @@ const App: React.FC = () => (
<Tooltip title="3 done / 3 in progress / 4 to do">
<Progress percent={60} success={{ percent: 30 }} />
</Tooltip>
<Tooltip title="3 done / 3 in progress / 4 to do">
<Progress percent={60} success={{ percent: 30 }} type="circle" />
</Tooltip>
<Tooltip title="3 done / 3 in progress / 4 to do">
<Progress percent={60} success={{ percent: 30 }} type="dashboard" />
<Progress percent={60} success={{ percent: 30 }} type="dashboard" style={{ marginLeft: 8 }} />
</Tooltip>
</>
);

View File

@ -5,6 +5,7 @@ import CloseOutlined from '@ant-design/icons/CloseOutlined';
import classNames from 'classnames';
import omit from 'rc-util/lib/omit';
import * as React from 'react';
import type { ConfigConsumerProps } from '../config-provider';
import { ConfigContext } from '../config-provider';
import { tuple } from '../_util/type';
import warning from '../_util/warning';
@ -12,7 +13,6 @@ import Circle from './Circle';
import Line from './Line';
import Steps from './Steps';
import { getSuccessPercent, validProgress } from './utils';
import useStyle from './style';
const ProgressTypes = tuple('line', 'circle', 'dashboard');
@ -54,7 +54,7 @@ export interface ProgressProps {
children?: React.ReactNode;
}
const Progress: React.FC<ProgressProps> = (props: ProgressProps) => {
const Progress: React.FC<ProgressProps> = props => {
const {
prefixCls: customizePrefixCls,
className,
@ -64,33 +64,37 @@ const Progress: React.FC<ProgressProps> = (props: ProgressProps) => {
size = 'default',
showInfo = true,
type = 'line',
status,
format,
...restProps
} = props;
function getPercentNumber() {
const percentNumber = React.useMemo<number>(() => {
const successPercent = getSuccessPercent(props);
return parseInt(
successPercent !== undefined ? successPercent.toString() : percent.toString(),
10,
);
}
}, [percent, props.success, props.successPercent]);
function getProgressStatus() {
const { status } = props;
if (!ProgressStatuses.includes(status!) && getPercentNumber() >= 100) {
const progressStatus = React.useMemo<typeof ProgressStatuses[number]>(() => {
if (!ProgressStatuses.includes(status!) && percentNumber >= 100) {
return 'success';
}
return status || 'normal';
}
}, [status, percentNumber]);
function renderProcessInfo(prefixCls: string, progressStatus: typeof ProgressStatuses[number]) {
const { format } = props;
const successPercent = getSuccessPercent(props);
const { getPrefixCls, direction } = React.useContext<ConfigConsumerProps>(ConfigContext);
const prefixCls = getPrefixCls('progress', customizePrefixCls);
const [wrapSSR, hashId] = useStyle(prefixCls);
const progressInfo = React.useMemo<React.ReactNode>(() => {
if (!showInfo) {
return null;
}
let text;
const textFormatter = format || (percentNumber => `${percentNumber}%`);
const successPercent = getSuccessPercent(props);
let text: React.ReactNode;
const textFormatter = format || (number => `${number}%`);
const isLineType = type === 'line';
if (format || (progressStatus !== 'exception' && progressStatus !== 'success')) {
text = textFormatter(validProgress(percent), validProgress(successPercent));
@ -105,14 +109,7 @@ const Progress: React.FC<ProgressProps> = (props: ProgressProps) => {
{text}
</span>
);
}
const { getPrefixCls, direction } = React.useContext(ConfigContext);
const prefixCls = getPrefixCls('progress', customizePrefixCls);
const [wrapSSR, hashId] = useStyle(prefixCls);
const progressStatus = getProgressStatus();
const progressInfo = renderProcessInfo(prefixCls, progressStatus);
}, [showInfo, percentNumber, progressStatus, type, prefixCls, format]);
warning(
!('successPercent' in props),
@ -156,6 +153,7 @@ const Progress: React.FC<ProgressProps> = (props: ProgressProps) => {
const classString = classNames(
prefixCls,
{
[`${prefixCls}-inline-circle`]: type === 'circle' && props.width! <= 20,
[`${prefixCls}-${(type === 'dashboard' && 'circle') || (steps && 'steps') || type}`]: true,
[`${prefixCls}-status-${progressStatus}`]: true,
[`${prefixCls}-show-info`]: showInfo,
@ -168,9 +166,8 @@ const Progress: React.FC<ProgressProps> = (props: ProgressProps) => {
return wrapSSR(
<div
className={classString}
{...omit(restProps, [
'status',
'format',
'trailColor',
'strokeWidth',
'width',
@ -180,7 +177,6 @@ const Progress: React.FC<ProgressProps> = (props: ProgressProps) => {
'success',
'successPercent',
])}
className={classString}
>
{progress}
</div>,

View File

@ -31,7 +31,7 @@ const antProgressActive = new Keyframes('antProgressActive', {
},
});
const genBaseStyle: GenerateStyle<ProgressToken> = (token: ProgressToken) => {
const genBaseStyle: GenerateStyle<ProgressToken> = token => {
const { componentCls: progressCls, iconCls: iconPrefixCls } = token;
return {
@ -113,7 +113,7 @@ const genBaseStyle: GenerateStyle<ProgressToken> = (token: ProgressToken) => {
[`${progressCls}-bg::before`]: {
position: 'absolute',
inset: 0,
background: token.colorBgContainer,
backgroundColor: token.colorBgContainer,
borderRadius: token.progressLineRadius,
opacity: 0,
animationName: antProgressActive,
@ -158,16 +158,11 @@ const genBaseStyle: GenerateStyle<ProgressToken> = (token: ProgressToken) => {
};
};
const genCircleStyle: GenerateStyle<ProgressToken> = (token: ProgressToken): CSSObject => {
const genCircleStyle: GenerateStyle<ProgressToken> = token => {
const { componentCls: progressCls, iconCls: iconPrefixCls } = token;
return {
[progressCls]: {
'&-circle': {
marginInlineEnd: token.marginXS,
marginBottom: token.marginXS,
},
[`${progressCls}-circle-trail`]: {
stroke: token.progressRemainingColor,
},
@ -208,6 +203,12 @@ const genCircleStyle: GenerateStyle<ProgressToken> = (token: ProgressToken): CSS
},
},
},
[`${progressCls}-inline-circle`]: {
lineHeight: 1,
[`${progressCls}-inner`]: {
verticalAlign: 'bottom',
},
},
};
};
@ -227,11 +228,11 @@ const genStepStyle: GenerateStyle<ProgressToken> = (token: ProgressToken): CSSOb
flexShrink: 0,
minWidth: token.progressStepMinWidth,
marginInlineEnd: token.progressStepMarginInlineEnd,
background: token.progressRemainingColor,
backgroundColor: token.progressRemainingColor,
transition: `all ${token.motionDurationSlow}`,
'&-active': {
background: token.colorInfo,
backgroundColor: token.colorInfo,
},
},
},

View File

@ -1,6 +1,9 @@
import { presetPrimaryColors } from '@ant-design/colors';
import type { CircleProps } from './Circle';
import type { ProgressProps } from './progress';
import warning from '../_util/warning';
export function validProgress(progress: number | undefined) {
export function validProgress(progress?: number) {
if (!progress || progress < 0) {
return 0;
}
@ -10,16 +13,7 @@ export function validProgress(progress: number | undefined) {
return progress;
}
export function getSuccessPercent({
success,
successPercent,
}: {
success?: {
progress?: number;
percent?: number;
};
successPercent?: number;
}) {
export function getSuccessPercent({ success, successPercent }: ProgressProps) {
let percent = successPercent;
/** @deprecated Use `percent` instead */
if (success && 'progress' in success) {
@ -35,3 +29,16 @@ export function getSuccessPercent({
}
return percent;
}
export const getPercentage = ({ percent, success, successPercent }: ProgressProps) => {
const realSuccessPercent = validProgress(getSuccessPercent({ success, successPercent }));
return [realSuccessPercent, validProgress(validProgress(percent) - realSuccessPercent)];
};
export const getStrokeColor = ({
success = {},
strokeColor,
}: Partial<CircleProps>): (string | Record<PropertyKey, string>)[] => {
const { strokeColor: successColor } = success;
return [successColor || presetPrimaryColors.green, strokeColor || null!];
};

View File

@ -1213,30 +1213,30 @@ Array [
class="ant-progress-circle-trail"
cx="50"
cy="50"
r="48"
r="46.25"
stroke-linecap="round"
stroke-width="4"
style="stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:0;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="7.5"
style="stroke-dasharray:290.59732045705584px 290.59732045705584;stroke-dashoffset:0;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
<circle
class="ant-progress-circle-path"
cx="50"
cy="50"
opacity="1"
r="48"
r="46.25"
stroke-linecap="round"
stroke-width="4"
style="stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:122.63715789784806;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="7.5"
style="stroke-dasharray:290.59732045705584px 290.59732045705584;stroke-dashoffset:119.98892818282235;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
<circle
class="ant-progress-circle-path"
cx="50"
cy="50"
opacity="0"
r="48"
r="46.25"
stroke-linecap="round"
stroke-width="4"
style="stroke:#52C41A;stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:301.58289474462015;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="7.5"
style="stroke:#52C41A;stroke-dasharray:290.59732045705584px 290.59732045705584;stroke-dashoffset:290.58732045705585;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
</svg>
<span
@ -1977,30 +1977,30 @@ exports[`renders ./components/steps/demo/progress.md extend context correctly 1`
class="ant-progress-circle-trail"
cx="50"
cy="50"
r="48"
r="46.25"
stroke-linecap="round"
stroke-width="4"
style="stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:0;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="7.5"
style="stroke-dasharray:290.59732045705584px 290.59732045705584;stroke-dashoffset:0;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
<circle
class="ant-progress-circle-path"
cx="50"
cy="50"
opacity="1"
r="48"
r="46.25"
stroke-linecap="round"
stroke-width="4"
style="stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:122.63715789784806;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="7.5"
style="stroke-dasharray:290.59732045705584px 290.59732045705584;stroke-dashoffset:119.98892818282235;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
<circle
class="ant-progress-circle-path"
cx="50"
cy="50"
opacity="0"
r="48"
r="46.25"
stroke-linecap="round"
stroke-width="4"
style="stroke:#52C41A;stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:301.58289474462015;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="7.5"
style="stroke:#52C41A;stroke-dasharray:290.59732045705584px 290.59732045705584;stroke-dashoffset:290.58732045705585;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
</svg>
<span
@ -2217,30 +2217,30 @@ Array [
class="ant-progress-circle-trail"
cx="50"
cy="50"
r="48"
r="46.25"
stroke-linecap="round"
stroke-width="4"
style="stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:0;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="7.5"
style="stroke-dasharray:290.59732045705584px 290.59732045705584;stroke-dashoffset:0;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
<circle
class="ant-progress-circle-path"
cx="50"
cy="50"
opacity="0"
r="48"
r="46.25"
stroke-linecap="round"
stroke-width="4"
style="stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:301.58289474462015;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="7.5"
style="stroke-dasharray:290.59732045705584px 290.59732045705584;stroke-dashoffset:290.58732045705585;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
<circle
class="ant-progress-circle-path"
cx="50"
cy="50"
opacity="0"
r="48"
r="46.25"
stroke-linecap="round"
stroke-width="4"
style="stroke:#52C41A;stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:301.58289474462015;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="7.5"
style="stroke:#52C41A;stroke-dasharray:290.59732045705584px 290.59732045705584;stroke-dashoffset:290.58732045705585;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
</svg>
<span
@ -2397,30 +2397,30 @@ Array [
class="ant-progress-circle-trail"
cx="50"
cy="50"
r="48"
r="45.3125"
stroke-linecap="round"
stroke-width="4"
style="stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:0;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="9.375"
style="stroke-dasharray:284.706834231575px 284.706834231575;stroke-dashoffset:0;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
<circle
class="ant-progress-circle-path"
cx="50"
cy="50"
opacity="0"
r="48"
r="45.3125"
stroke-linecap="round"
stroke-width="4"
style="stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:301.58289474462015;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="9.375"
style="stroke-dasharray:284.706834231575px 284.706834231575;stroke-dashoffset:284.696834231575;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
<circle
class="ant-progress-circle-path"
cx="50"
cy="50"
opacity="0"
r="48"
r="45.3125"
stroke-linecap="round"
stroke-width="4"
style="stroke:#52C41A;stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:301.58289474462015;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="9.375"
style="stroke:#52C41A;stroke-dasharray:284.706834231575px 284.706834231575;stroke-dashoffset:284.696834231575;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
</svg>
<span
@ -2577,30 +2577,30 @@ Array [
class="ant-progress-circle-trail"
cx="50"
cy="50"
r="48"
r="46.25"
stroke-linecap="round"
stroke-width="4"
style="stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:0;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="7.5"
style="stroke-dasharray:290.59732045705584px 290.59732045705584;stroke-dashoffset:0;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
<circle
class="ant-progress-circle-path"
cx="50"
cy="50"
opacity="0"
r="48"
r="46.25"
stroke-linecap="round"
stroke-width="4"
style="stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:301.58289474462015;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="7.5"
style="stroke-dasharray:290.59732045705584px 290.59732045705584;stroke-dashoffset:290.58732045705585;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
<circle
class="ant-progress-circle-path"
cx="50"
cy="50"
opacity="0"
r="48"
r="46.25"
stroke-linecap="round"
stroke-width="4"
style="stroke:#52C41A;stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:301.58289474462015;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="7.5"
style="stroke:#52C41A;stroke-dasharray:290.59732045705584px 290.59732045705584;stroke-dashoffset:290.58732045705585;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
</svg>
<span
@ -2757,30 +2757,30 @@ Array [
class="ant-progress-circle-trail"
cx="50"
cy="50"
r="48"
r="45.3125"
stroke-linecap="round"
stroke-width="4"
style="stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:0;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="9.375"
style="stroke-dasharray:284.706834231575px 284.706834231575;stroke-dashoffset:0;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
<circle
class="ant-progress-circle-path"
cx="50"
cy="50"
opacity="0"
r="48"
r="45.3125"
stroke-linecap="round"
stroke-width="4"
style="stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:301.58289474462015;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="9.375"
style="stroke-dasharray:284.706834231575px 284.706834231575;stroke-dashoffset:284.696834231575;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
<circle
class="ant-progress-circle-path"
cx="50"
cy="50"
opacity="0"
r="48"
r="45.3125"
stroke-linecap="round"
stroke-width="4"
style="stroke:#52C41A;stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:301.58289474462015;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="9.375"
style="stroke:#52C41A;stroke-dasharray:284.706834231575px 284.706834231575;stroke-dashoffset:284.696834231575;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
</svg>
<span

View File

@ -1069,30 +1069,30 @@ Array [
class="ant-progress-circle-trail"
cx="50"
cy="50"
r="48"
r="46.25"
stroke-linecap="round"
stroke-width="4"
style="stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:0;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="7.5"
style="stroke-dasharray:290.59732045705584px 290.59732045705584;stroke-dashoffset:0;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
<circle
class="ant-progress-circle-path"
cx="50"
cy="50"
opacity="1"
r="48"
r="46.25"
stroke-linecap="round"
stroke-width="4"
style="stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:122.63715789784806;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="7.5"
style="stroke-dasharray:290.59732045705584px 290.59732045705584;stroke-dashoffset:119.98892818282235;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
<circle
class="ant-progress-circle-path"
cx="50"
cy="50"
opacity="0"
r="48"
r="46.25"
stroke-linecap="round"
stroke-width="4"
style="stroke:#52C41A;stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:301.58289474462015;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="7.5"
style="stroke:#52C41A;stroke-dasharray:290.59732045705584px 290.59732045705584;stroke-dashoffset:290.58732045705585;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
</svg>
<span
@ -1833,30 +1833,30 @@ exports[`renders ./components/steps/demo/progress.md correctly 1`] = `
class="ant-progress-circle-trail"
cx="50"
cy="50"
r="48"
r="46.25"
stroke-linecap="round"
stroke-width="4"
style="stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:0;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="7.5"
style="stroke-dasharray:290.59732045705584px 290.59732045705584;stroke-dashoffset:0;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
<circle
class="ant-progress-circle-path"
cx="50"
cy="50"
opacity="1"
r="48"
r="46.25"
stroke-linecap="round"
stroke-width="4"
style="stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:122.63715789784806;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="7.5"
style="stroke-dasharray:290.59732045705584px 290.59732045705584;stroke-dashoffset:119.98892818282235;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
<circle
class="ant-progress-circle-path"
cx="50"
cy="50"
opacity="0"
r="48"
r="46.25"
stroke-linecap="round"
stroke-width="4"
style="stroke:#52C41A;stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:301.58289474462015;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="7.5"
style="stroke:#52C41A;stroke-dasharray:290.59732045705584px 290.59732045705584;stroke-dashoffset:290.58732045705585;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
</svg>
<span
@ -2073,30 +2073,30 @@ Array [
class="ant-progress-circle-trail"
cx="50"
cy="50"
r="48"
r="46.25"
stroke-linecap="round"
stroke-width="4"
style="stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:0;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="7.5"
style="stroke-dasharray:290.59732045705584px 290.59732045705584;stroke-dashoffset:0;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
<circle
class="ant-progress-circle-path"
cx="50"
cy="50"
opacity="0"
r="48"
r="46.25"
stroke-linecap="round"
stroke-width="4"
style="stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:301.58289474462015;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="7.5"
style="stroke-dasharray:290.59732045705584px 290.59732045705584;stroke-dashoffset:290.58732045705585;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
<circle
class="ant-progress-circle-path"
cx="50"
cy="50"
opacity="0"
r="48"
r="46.25"
stroke-linecap="round"
stroke-width="4"
style="stroke:#52C41A;stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:301.58289474462015;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="7.5"
style="stroke:#52C41A;stroke-dasharray:290.59732045705584px 290.59732045705584;stroke-dashoffset:290.58732045705585;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
</svg>
<span
@ -2253,30 +2253,30 @@ Array [
class="ant-progress-circle-trail"
cx="50"
cy="50"
r="48"
r="45.3125"
stroke-linecap="round"
stroke-width="4"
style="stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:0;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="9.375"
style="stroke-dasharray:284.706834231575px 284.706834231575;stroke-dashoffset:0;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
<circle
class="ant-progress-circle-path"
cx="50"
cy="50"
opacity="0"
r="48"
r="45.3125"
stroke-linecap="round"
stroke-width="4"
style="stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:301.58289474462015;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="9.375"
style="stroke-dasharray:284.706834231575px 284.706834231575;stroke-dashoffset:284.696834231575;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
<circle
class="ant-progress-circle-path"
cx="50"
cy="50"
opacity="0"
r="48"
r="45.3125"
stroke-linecap="round"
stroke-width="4"
style="stroke:#52C41A;stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:301.58289474462015;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="9.375"
style="stroke:#52C41A;stroke-dasharray:284.706834231575px 284.706834231575;stroke-dashoffset:284.696834231575;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
</svg>
<span
@ -2433,30 +2433,30 @@ Array [
class="ant-progress-circle-trail"
cx="50"
cy="50"
r="48"
r="46.25"
stroke-linecap="round"
stroke-width="4"
style="stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:0;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="7.5"
style="stroke-dasharray:290.59732045705584px 290.59732045705584;stroke-dashoffset:0;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
<circle
class="ant-progress-circle-path"
cx="50"
cy="50"
opacity="0"
r="48"
r="46.25"
stroke-linecap="round"
stroke-width="4"
style="stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:301.58289474462015;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="7.5"
style="stroke-dasharray:290.59732045705584px 290.59732045705584;stroke-dashoffset:290.58732045705585;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
<circle
class="ant-progress-circle-path"
cx="50"
cy="50"
opacity="0"
r="48"
r="46.25"
stroke-linecap="round"
stroke-width="4"
style="stroke:#52C41A;stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:301.58289474462015;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="7.5"
style="stroke:#52C41A;stroke-dasharray:290.59732045705584px 290.59732045705584;stroke-dashoffset:290.58732045705585;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
</svg>
<span
@ -2613,30 +2613,30 @@ Array [
class="ant-progress-circle-trail"
cx="50"
cy="50"
r="48"
r="45.3125"
stroke-linecap="round"
stroke-width="4"
style="stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:0;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="9.375"
style="stroke-dasharray:284.706834231575px 284.706834231575;stroke-dashoffset:0;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
<circle
class="ant-progress-circle-path"
cx="50"
cy="50"
opacity="0"
r="48"
r="45.3125"
stroke-linecap="round"
stroke-width="4"
style="stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:301.58289474462015;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="9.375"
style="stroke-dasharray:284.706834231575px 284.706834231575;stroke-dashoffset:284.696834231575;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
<circle
class="ant-progress-circle-path"
cx="50"
cy="50"
opacity="0"
r="48"
r="45.3125"
stroke-linecap="round"
stroke-width="4"
style="stroke:#52C41A;stroke-dasharray:301.59289474462014px 301.59289474462014;stroke-dashoffset:301.58289474462015;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
stroke-width="9.375"
style="stroke:#52C41A;stroke-dasharray:284.706834231575px 284.706834231575;stroke-dashoffset:284.696834231575;transform:rotate(-90deg);transform-origin:50% 50%;transition:stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;fill-opacity:0"
/>
</svg>
<span