-
+exports[`Progress steps should have default percent 0 1`] = `
+
+
`;
diff --git a/components/progress/__tests__/index.test.js b/components/progress/__tests__/index.test.js
index 1eadc98aee..218521be35 100644
--- a/components/progress/__tests__/index.test.js
+++ b/components/progress/__tests__/index.test.js
@@ -1,13 +1,15 @@
import { mount } from '@vue/test-utils';
import { asyncExpect } from '@/tests/utils';
+import { handleGradient, sortGradient } from '../Line';
import Progress from '..';
+import ProgressSteps from '../Steps';
describe('Progress', () => {
it('successPercent should decide the progress status when it exists', async () => {
const wrapper = mount(Progress, {
props: {
percent: 100,
- successPercent: 50,
+ success: { percent: 50 },
},
sync: false,
});
@@ -15,12 +17,12 @@ describe('Progress', () => {
expect(wrapper.findAll('.ant-progress-status-success')).toHaveLength(0);
});
- wrapper.setProps({ percent: 50, successPercent: 100 });
+ wrapper.setProps({ percent: 50, success: { percent: 100 } });
await asyncExpect(() => {
expect(wrapper.findAll('.ant-progress-status-success')).toHaveLength(1);
});
- wrapper.setProps({ percent: 100, successPercent: 0 });
+ wrapper.setProps({ percent: 100, success: { percent: 0 } });
await asyncExpect(() => {
expect(wrapper.findAll('.ant-progress-status-success')).toHaveLength(0);
});
@@ -51,7 +53,7 @@ describe('Progress', () => {
});
});
- it('render negetive progress', async () => {
+ it('render negative progress', async () => {
const wrapper = mount(Progress, {
props: {
percent: -20,
@@ -63,11 +65,11 @@ describe('Progress', () => {
});
});
- it('render negetive successPercent', async () => {
+ it('render negative successPercent', async () => {
const wrapper = mount(Progress, {
props: {
percent: 50,
- successPercent: -20,
+ success: { percent: -20 },
},
sync: false,
});
@@ -76,7 +78,7 @@ describe('Progress', () => {
});
});
- it('render negetive successPercent', async () => {
+ it('render format', async () => {
const wrapper = mount(Progress, {
props: {
percent: 50,
@@ -90,7 +92,7 @@ describe('Progress', () => {
});
});
- it('render format', async () => {
+ it('render strokeColor', async () => {
const wrapper = mount(Progress, {
props: {
percent: 50,
@@ -102,10 +104,217 @@ describe('Progress', () => {
await asyncExpect(() => {
expect(wrapper.html()).toMatchSnapshot();
});
+ wrapper.setProps({
+ strokeColor: {
+ from: '#108ee9',
+ to: '#87d068',
+ },
+ type: 'line',
+ });
+ await asyncExpect(() => {
+ expect(wrapper.html()).toMatchSnapshot();
+ });
+ wrapper.setProps({
+ strokeColor: {
+ '0%': '#108ee9',
+ '100%': '#87d068',
+ },
+ });
+ await asyncExpect(() => {
+ expect(wrapper.html()).toMatchSnapshot();
+ });
});
it('render normal progress', () => {
const wrapper = mount(Progress, { props: { status: 'normal' } });
expect(wrapper.html()).toMatchSnapshot();
});
+
+ it('render trailColor progress', () => {
+ const wrapper = mount({
+ render() {
+ return
;
+ },
+ });
+ expect(wrapper.html()).toMatchSnapshot();
+ });
+
+ it('render successColor progress', () => {
+ const wrapper = mount({
+ render() {
+ return
;
+ },
+ });
+ expect(wrapper.html()).toMatchSnapshot();
+ });
+
+ it('render dashboard zero gapDegree', () => {
+ const wrapper = mount({
+ render() {
+ return
;
+ },
+ });
+ expect(wrapper.html()).toMatchSnapshot();
+ });
+
+ it('render dashboard 295 gapDegree', () => {
+ const wrapper = mount({
+ render() {
+ return
;
+ },
+ });
+ expect(wrapper.html()).toMatchSnapshot();
+ });
+
+ it('render dashboard 296 gapDegree', () => {
+ const wrapper = mount({
+ render() {
+ return
;
+ },
+ });
+ expect(wrapper.html()).toMatchSnapshot();
+ });
+
+ it('get correct line-gradient', () => {
+ expect(handleGradient({ from: 'test', to: 'test' }).backgroundImage).toBe(
+ 'linear-gradient(to right, test, test)',
+ );
+ expect(handleGradient({}).backgroundImage).toBe('linear-gradient(to right, #1890ff, #1890ff)');
+ expect(handleGradient({ from: 'test', to: 'test', '0%': 'test' }).backgroundImage).toBe(
+ 'linear-gradient(to right, test 0%)',
+ );
+ });
+
+ it('sort gradients correctly', () => {
+ expect(sortGradient({ '10%': 'test10', '30%': 'test30', '20%': 'test20' })).toBe(
+ 'test10 10%, test20 20%, test30 30%',
+ );
+ expect(sortGradient({ '10%': 'test10', '30%': 'test30', '20%': 'test20', dummy: 'test' })).toBe(
+ 'test10 10%, test20 20%, test30 30%',
+ );
+ });
+
+ it('should show success status when percent is 100', () => {
+ const wrapper = mount({
+ render() {
+ return
;
+ },
+ });
+ expect(wrapper.findAll('.ant-progress-status-success')).toHaveLength(1);
+ });
+
+ // https://github.com/ant-design/ant-design/issues/15950
+ it('should show success status when percent is 100 and status is undefined', () => {
+ const wrapper = mount({
+ render() {
+ return
;
+ },
+ });
+ expect(wrapper.findAll('.ant-progress-status-success')).toHaveLength(1);
+ });
+
+ // https://github.com/ant-design/ant-design/pull/15951#discussion_r273062969
+ it('should show success status when status is invalid', () => {
+ const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
+ const wrapper = mount({
+ render() {
+ return
;
+ },
+ });
+ expect(wrapper.findAll('.ant-progress-status-success')).toHaveLength(1);
+ errorSpy.mockRestore();
+ });
+
+ it('should support steps', () => {
+ const wrapper = mount({
+ render() {
+ return
;
+ },
+ });
+ expect(wrapper.html()).toMatchSnapshot();
+ });
+
+ it('steps should be changable', async () => {
+ const wrapper = mount({
+ render() {
+ return
;
+ },
+ });
+ expect(wrapper.findAll('.ant-progress-steps-item-active').length).toBe(3);
+ wrapper.setProps({ percent: 40 });
+ await asyncExpect(() => {
+ expect(wrapper.findAll('.ant-progress-steps-item-active').length).toBe(2);
+ });
+ });
+
+ it('steps should be changable when has strokeColor', async () => {
+ const wrapper = mount({
+ render() {
+ return
;
+ },
+ });
+ expect(wrapper.findAll('.ant-progress-steps-item')[0].element.style.backgroundColor).toBe(
+ 'rgb(24, 144, 255)',
+ );
+ wrapper.setProps({ percent: 40 });
+ await asyncExpect(() => {
+ expect(wrapper.findAll('.ant-progress-steps-item')[2].element.style.backgroundColor).toBe('');
+ expect(wrapper.findAll('.ant-progress-steps-item')[1].element.style.backgroundColor).toBe(
+ 'rgb(24, 144, 255)',
+ );
+ });
+ });
+
+ it('steps should support trailColor', () => {
+ const wrapper = mount(
);
+ expect(wrapper.findAll('.ant-progress-steps-item')[1].element.style.backgroundColor).toBe(
+ 'rgb(24, 144, 238)',
+ );
+ });
+
+ it('should display correct step', async () => {
+ const wrapper = mount({
+ render() {
+ return
;
+ },
+ });
+ expect(wrapper.findAll('.ant-progress-steps-item-active').length).toBe(2);
+ wrapper.setProps({ percent: 33.33 });
+ await asyncExpect(() => {
+ expect(wrapper.findAll('.ant-progress-steps-item-active').length).toBe(3);
+ });
+ wrapper.setProps({ percent: 44.44 });
+ await asyncExpect(() => {
+ expect(wrapper.findAll('.ant-progress-steps-item-active').length).toBe(4);
+ });
+ });
+
+ it('steps should have default percent 0', () => {
+ const wrapper = mount({
+ render() {
+ return
;
+ },
+ });
+ expect(wrapper.html()).toMatchSnapshot();
+ });
+
+ it('should warning if use `progress` in success', () => {
+ const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
+ mount(
);
+ expect(errorSpy).toHaveBeenCalledWith(
+ 'Warning: [ant-design-vue: Progress] `success.progress` is deprecated. Please use `success.percent` instead.',
+ );
+ });
+
+ it('should warning if use `progress` in success in type Circle', () => {
+ const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
+ mount({
+ render() {
+ return
;
+ },
+ });
+ expect(errorSpy).toHaveBeenCalledWith(
+ 'Warning: [ant-design-vue: Progress] `success.progress` is deprecated. Please use `success.percent` instead.',
+ );
+ });
});
diff --git a/components/progress/circle.tsx b/components/progress/circle.tsx
deleted file mode 100644
index bbf6867e77..0000000000
--- a/components/progress/circle.tsx
+++ /dev/null
@@ -1,86 +0,0 @@
-import type { ExtractPropTypes } from 'vue';
-import { defineComponent } from 'vue';
-import { Circle as VCCircle } from '../vc-progress';
-import PropTypes from '../_util/vue-types';
-import { validProgress } from './utils';
-import { ProgressProps } from './props';
-
-const CircleProps = {
- ...ProgressProps,
- progressStatus: PropTypes.string,
-};
-
-const statusColorMap: Record
= {
- normal: '#108ee9',
- exception: '#ff5500',
- success: '#87d068',
-};
-
-export type ICircleProps = ExtractPropTypes;
-
-function getPercentage({ percent, successPercent }: ICircleProps) {
- const ptg = validProgress(percent);
- if (!successPercent) return ptg;
-
- const successPtg = validProgress(successPercent);
- return [successPercent, validProgress(ptg - successPtg)];
-}
-
-function getStrokeColor({ progressStatus, successPercent, strokeColor }: ICircleProps) {
- const color = strokeColor || statusColorMap[progressStatus];
- if (!successPercent) return color;
- return [statusColorMap.success, color];
-}
-
-const Circle = defineComponent({
- props: CircleProps,
- setup(props, { slots }) {
- return () => {
- const {
- prefixCls,
- width,
- strokeWidth,
- trailColor,
- strokeLinecap,
- gapPosition,
- gapDegree,
- type,
- } = props;
- const circleSize = width || 120;
- const circleStyle = {
- width: typeof circleSize === 'number' ? `${circleSize}px` : circleSize,
- height: typeof circleSize === 'number' ? `${circleSize}px` : circleSize,
- fontSize: `${circleSize * 0.15 + 6}px`,
- };
- const circleWidth = strokeWidth || 6;
- const gapPos = gapPosition || (type === 'dashboard' && 'bottom') || 'top';
- const gapDeg = gapDegree || (type === 'dashboard' && 75);
- const strokeColor = getStrokeColor(props);
- const isGradient = Object.prototype.toString.call(strokeColor) === '[object Object]';
-
- const wrapperClassName = {
- [`${prefixCls}-inner`]: true,
- [`${prefixCls}-circle-gradient`]: isGradient,
- };
-
- return (
-
-
- {slots?.default()}
-
- );
- };
- },
-});
-
-export default Circle;
diff --git a/components/progress/index.ts b/components/progress/index.ts
index ef45c8e8e1..2505b42832 100644
--- a/components/progress/index.ts
+++ b/components/progress/index.ts
@@ -1,6 +1,6 @@
import Progress from './progress';
import { withInstall } from '../_util/type';
-export { ProgressProps } from './props';
+export type { ProgressProps } from './props';
export default withInstall(Progress);
diff --git a/components/progress/line.tsx b/components/progress/line.tsx
deleted file mode 100644
index 06afa96854..0000000000
--- a/components/progress/line.tsx
+++ /dev/null
@@ -1,93 +0,0 @@
-import { validProgress } from './utils';
-
-/**
- * {
- * '0%': '#afc163',
- * '75%': '#009900',
- * '50%': 'green', ====> '#afc163 0%, #66FF00 25%, #00CC00 50%, #009900 75%, #ffffff 100%'
- * '25%': '#66FF00',
- * '100%': '#ffffff'
- * }
- */
-export const sortGradient = gradients => {
- let tempArr = [];
- // eslint-disable-next-line no-restricted-syntax
- for (const [key, value] of Object.entries(gradients)) {
- const formatKey = parseFloat(key.replace(/%/g, ''));
- if (isNaN(formatKey)) {
- return {};
- }
- tempArr.push({
- key: formatKey,
- value,
- });
- }
- tempArr = tempArr.sort((a, b) => a.key - b.key);
- return tempArr.map(({ key, value }) => `${value} ${key}%`).join(', ');
-};
-
-/**
- * {
- * '0%': '#afc163',
- * '25%': '#66FF00',
- * '50%': '#00CC00', ====> linear-gradient(to right, #afc163 0%, #66FF00 25%,
- * '75%': '#009900', #00CC00 50%, #009900 75%, #ffffff 100%)
- * '100%': '#ffffff'
- * }
- *
- * Then this man came to realize the truth:
- * Besides six pence, there is the moon.
- * Besides bread and butter, there is the bug.
- * And...
- * Besides women, there is the code.
- */
-export const handleGradient = strokeColor => {
- const { from = '#1890ff', to = '#1890ff', direction = 'to right', ...rest } = strokeColor;
- if (Object.keys(rest).length !== 0) {
- const sortedGradients = sortGradient(rest);
- return { backgroundImage: `linear-gradient(${direction}, ${sortedGradients})` };
- }
- return { backgroundImage: `linear-gradient(${direction}, ${from}, ${to})` };
-};
-
-const Line = (_, { attrs, slots }) => {
- const { prefixCls, percent, successPercent, strokeWidth, size, strokeColor, strokeLinecap } =
- attrs;
- let backgroundProps;
- if (strokeColor && typeof strokeColor !== 'string') {
- backgroundProps = handleGradient(strokeColor);
- } else {
- backgroundProps = {
- background: strokeColor,
- };
- }
- const percentStyle = {
- width: `${validProgress(percent)}%`,
- height: `${strokeWidth || (size === 'small' ? 6 : 8)}px`,
- background: strokeColor,
- borderRadius: strokeLinecap === 'square' ? 0 : '100px',
- ...backgroundProps,
- };
- const successPercentStyle = {
- width: `${validProgress(successPercent)}%`,
- height: `${strokeWidth || (size === 'small' ? 6 : 8)}px`,
- borderRadius: strokeLinecap === 'square' ? 0 : '',
- };
- const successSegment =
- successPercent !== undefined ? (
-
- ) : null;
- return (
-
- );
-};
-
-export default Line;
diff --git a/components/progress/progress.tsx b/components/progress/progress.tsx
index 118732db82..c8d2e1c700 100644
--- a/components/progress/progress.tsx
+++ b/components/progress/progress.tsx
@@ -1,20 +1,22 @@
-import { defineComponent, inject } from 'vue';
-import classNames from '../_util/classNames';
-import { getOptionProps } from '../_util/props-util';
+import type { VNodeChild } from 'vue';
+import { computed, defineComponent } from 'vue';
import initDefaultProps from '../_util/props-util/initDefaultProps';
-import { defaultConfigProvider } from '../config-provider';
import CloseOutlined from '@ant-design/icons-vue/CloseOutlined';
import CheckOutlined from '@ant-design/icons-vue/CheckOutlined';
import CheckCircleFilled from '@ant-design/icons-vue/CheckCircleFilled';
import CloseCircleFilled from '@ant-design/icons-vue/CloseCircleFilled';
-import Line from './line';
-import Circle from './circle';
-import { validProgress } from './utils';
-import { ProgressProps, ProgressStatuses } from './props';
+import Line from './Line';
+import Circle from './Circle';
+import Steps from './Steps';
+import { getSuccessPercent, validProgress } from './utils';
+import useConfigInject from '../_util/hooks/useConfigInject';
+import devWarning from '../vc-util/devWarning';
+import type { ProgressStatusesType } from './props';
+import { progressProps, progressStatuses } from './props';
export default defineComponent({
name: 'AProgress',
- props: initDefaultProps(ProgressProps, {
+ props: initDefaultProps(progressProps, {
type: 'line',
percent: 0,
showInfo: true,
@@ -24,37 +26,49 @@ export default defineComponent({
gapDegree: 0,
strokeLinecap: 'round',
}),
- setup() {
- return {
- configProvider: inject('configProvider', defaultConfigProvider),
- };
- },
- methods: {
- getPercentNumber() {
- const { successPercent, percent = 0 } = this.$props;
+ setup(props, { slots }) {
+ const { prefixCls, direction } = useConfigInject('progress', props);
+
+ const classString = computed(() => {
+ const { type, showInfo, size } = props;
+ const pre = prefixCls.value;
+ return {
+ [pre]: true,
+ [`${pre}-${(type === 'dashboard' && 'circle') || type}`]: true,
+ [`${pre}-show-info`]: showInfo,
+ [`${pre}-${size}`]: size,
+ [`${pre}-rtl`]: direction.value === 'rtl',
+ };
+ });
+
+ const getPercentNumber = () => {
+ const { percent = 0 } = props;
+ const successPercent = getSuccessPercent(props.success, props.successPercent);
return parseInt(
successPercent !== undefined ? successPercent.toString() : percent.toString(),
10,
);
- },
+ };
- getProgressStatus() {
- const { status } = this.$props;
- if (ProgressStatuses.indexOf(status) < 0 && this.getPercentNumber() >= 100) {
+ const getProgressStatus = () => {
+ const { status } = props;
+ if (progressStatuses.indexOf(status) < 0 && getPercentNumber() >= 100) {
return 'success';
}
return status || 'normal';
- },
- renderProcessInfo(prefixCls: string, progressStatus: typeof ProgressStatuses[number]) {
- const { showInfo, format, type, percent, successPercent } = this.$props;
+ };
+
+ const renderProcessInfo = (prefixCls: string, progressStatus: ProgressStatusesType) => {
+ const { showInfo, format, type, percent } = props;
+ const successPercent = getSuccessPercent(props.success, props.successPercent);
if (!showInfo) return null;
- let text;
- const textFormatter = format || this.$slots.format || (percentNumber => `${percentNumber}%`);
+ let text: VNodeChild;
+ const textFormatter = format || slots?.format || (percentNumber => `${percentNumber}%`);
const isLineType = type === 'line';
if (
format ||
- this.$slots.format ||
+ slots?.format ||
(progressStatus !== 'exception' && progressStatus !== 'success')
) {
text = textFormatter(validProgress(percent), validProgress(successPercent));
@@ -68,44 +82,50 @@ export default defineComponent({
{text}
);
- },
- },
- render() {
- const props = getOptionProps(this);
- const { prefixCls: customizePrefixCls, size, type, showInfo } = props;
- const { getPrefixCls } = this.configProvider;
- const prefixCls = getPrefixCls('progress', customizePrefixCls);
- const progressStatus = this.getProgressStatus();
- const progressInfo = this.renderProcessInfo(prefixCls, progressStatus);
+ };
- let progress;
+ return () => {
+ const { type, steps, strokeColor } = props;
+ const progressStatus = getProgressStatus();
+ const progressInfo = renderProcessInfo(prefixCls.value, progressStatus);
- // Render progress shape
- if (type === 'line') {
- const lineProps = {
- ...props,
- prefixCls,
- };
- progress = {progressInfo};
- } else if (type === 'circle' || type === 'dashboard') {
- const circleProps = {
- ...props,
- prefixCls,
- progressStatus,
- };
- progress = {progressInfo};
- }
+ devWarning(
+ props.successPercent == undefined,
+ 'Progress',
+ '`successPercent` is deprecated. Please use `success.percent` instead.',
+ );
- const classString = classNames(prefixCls, {
- [`${prefixCls}-${(type === 'dashboard' && 'circle') || type}`]: true,
- [`${prefixCls}-status-${progressStatus}`]: true,
- [`${prefixCls}-show-info`]: showInfo,
- [`${prefixCls}-${size}`]: size,
- });
+ let progress: VNodeChild;
+ // Render progress shape
+ if (type === 'line') {
+ progress = steps ? (
+
+ {progressInfo}
+
+ ) : (
+
+ {progressInfo}
+
+ );
+ } else if (type === 'circle' || type === 'dashboard') {
+ progress = (
+
+ {progressInfo}
+
+ );
+ }
+
+ const classNames = {
+ ...classString.value,
+ [`${prefixCls.value}-status-${progressStatus}`]: true,
+ };
- const progressProps = {
- class: classString,
+ return {progress}
;
};
- return {progress}
;
},
});
diff --git a/components/progress/props.ts b/components/progress/props.ts
index a18b1c7c24..7933fdf472 100644
--- a/components/progress/props.ts
+++ b/components/progress/props.ts
@@ -1,24 +1,48 @@
import PropTypes from '../_util/vue-types';
import { tuple } from '../_util/type';
+import type { PropType, VNodeChild, ExtractPropTypes } from 'vue';
-export const ProgressStatuses = tuple('normal', 'exception', 'active', 'success');
-export const ProgressType = PropTypes.oneOf(tuple('line', 'circle', 'dashboard'));
-export const ProgressSize = PropTypes.oneOf(tuple('default', 'small'));
+export const progressStatuses = tuple('normal', 'exception', 'active', 'success');
+export type ProgressStatusesType = typeof progressStatuses[number];
+const ProgressType = tuple('line', 'circle', 'dashboard');
+export type ProgressType = typeof ProgressType[number];
+const ProgressSize = tuple('default', 'small');
+export type ProgressSize = typeof ProgressSize[number];
+export type StringGradients = { [percentage: string]: string };
+type FromToGradients = { from: string; to: string };
+export type ProgressGradient = { direction?: string } & (StringGradients | FromToGradients);
-export const ProgressProps = {
+export interface SuccessProps {
+ percent?: number;
+ /** @deprecated Use `percent` instead */
+ progress?: number;
+ strokeColor?: string;
+}
+
+export const progressProps = {
prefixCls: PropTypes.string,
- type: ProgressType,
+ type: PropTypes.oneOf(ProgressType),
percent: PropTypes.number,
- successPercent: PropTypes.number,
- format: PropTypes.func,
- status: PropTypes.oneOf(ProgressStatuses),
+ format: { type: Function as PropType<(percent?: number, successPercent?: number) => VNodeChild> },
+ status: PropTypes.oneOf(progressStatuses),
showInfo: PropTypes.looseBool,
strokeWidth: PropTypes.number,
- strokeLinecap: PropTypes.oneOf(['butt', 'round', 'square']),
- strokeColor: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
+ strokeLinecap: PropTypes.oneOf(tuple('butt', 'round', 'square')),
+ strokeColor: {
+ type: [String, Object] as PropType,
+ },
trailColor: PropTypes.string,
width: PropTypes.number,
+ success: {
+ type: Object as PropType,
+ default: (): SuccessProps => ({}),
+ },
gapDegree: PropTypes.number,
gapPosition: PropTypes.oneOf(tuple('top', 'bottom', 'left', 'right')),
- size: ProgressSize,
+ size: PropTypes.oneOf(ProgressSize),
+ steps: PropTypes.number,
+ /** @deprecated Use `success` instead */
+ successPercent: PropTypes.number,
};
+
+export type ProgressProps = Partial>;
diff --git a/components/progress/style/index.less b/components/progress/style/index.less
index f2f0bd5e8c..45fc23e7c0 100644
--- a/components/progress/style/index.less
+++ b/components/progress/style/index.less
@@ -14,6 +14,26 @@
font-size: @font-size-base;
}
+ &-steps {
+ display: inline-block;
+ &-outer {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ }
+ &-item {
+ flex-shrink: 0;
+ min-width: 2px;
+ margin-right: 2px;
+ background: @progress-steps-item-bg;
+ transition: all 0.3s;
+
+ &-active {
+ background: @progress-default-color;
+ }
+ }
+ }
+
&-small&-line,
&-small&-line &-text .@{iconfont-css-prefix} {
font-size: @font-size-sm;
@@ -73,8 +93,8 @@
display: inline-block;
width: 2em;
margin-left: 8px;
- color: @text-color-secondary;
- font-size: 1em;
+ color: @progress-info-text-color;
+ font-size: @progress-text-font-size;
line-height: 1;
white-space: nowrap;
text-align: left;
@@ -144,6 +164,7 @@
margin: 0;
padding: 0;
color: @progress-text-color;
+ font-size: @progress-circle-text-font-size;
line-height: 1;
white-space: normal;
text-align: center;
@@ -180,3 +201,5 @@
opacity: 0;
}
}
+
+@import './rtl';
diff --git a/components/progress/style/rtl.less b/components/progress/style/rtl.less
new file mode 100644
index 0000000000..0756b5f847
--- /dev/null
+++ b/components/progress/style/rtl.less
@@ -0,0 +1,37 @@
+@import '../../style/themes/index';
+@import '../../style/mixins/index';
+
+@progress-prefix-cls: ~'@{ant-prefix}-progress';
+
+.@{progress-prefix-cls} {
+ &-rtl {
+ direction: rtl;
+ }
+
+ &-outer {
+ .@{progress-prefix-cls}-show-info & {
+ .@{progress-prefix-cls}-rtl& {
+ margin-right: 0;
+ margin-left: ~'calc(-2em - 8px)';
+ padding-right: 0;
+ padding-left: ~'calc(2em + 8px)';
+ }
+ }
+ }
+
+ &-success-bg {
+ .@{progress-prefix-cls}-rtl & {
+ right: 0;
+ left: auto;
+ }
+ }
+
+ &-line &-text,
+ &-steps &-text {
+ .@{progress-prefix-cls}-rtl& {
+ margin-right: 8px;
+ margin-left: 0;
+ text-align: right;
+ }
+ }
+}
diff --git a/components/progress/utils.ts b/components/progress/utils.ts
index 14a930d882..df8b332265 100644
--- a/components/progress/utils.ts
+++ b/components/progress/utils.ts
@@ -1,4 +1,7 @@
-export function validProgress(progress?: number) {
+import devWarning from '../vc-util/devWarning';
+import type { ProgressProps } from './props';
+
+export function validProgress(progress: number | undefined) {
if (!progress || progress < 0) {
return 0;
}
@@ -7,3 +10,23 @@ export function validProgress(progress?: number) {
}
return progress;
}
+
+export function getSuccessPercent(
+ success?: ProgressProps['success'],
+ successPercent?: ProgressProps['successPercent'],
+) {
+ let percent = successPercent;
+ /** @deprecated Use `percent` instead */
+ if (success && 'progress' in success) {
+ devWarning(
+ false,
+ 'Progress',
+ '`success.progress` is deprecated. Please use `success.percent` instead.',
+ );
+ percent = success.progress;
+ }
+ if (success && 'percent' in success) {
+ percent = success.percent;
+ }
+ return percent;
+}
diff --git a/components/style/themes/default.less b/components/style/themes/default.less
index 1b9b0c3013..dd886957e1 100644
--- a/components/style/themes/default.less
+++ b/components/style/themes/default.less
@@ -496,9 +496,12 @@
// --
@progress-default-color: @processing-color;
@progress-remaining-color: @background-color-base;
-@progress-text-color: @text-color;
+@progress-info-text-color: @progress-text-color;
@progress-radius: 100px;
-
+@progress-steps-item-bg: #f3f3f3;
+@progress-text-font-size: 1em;
+@progress-text-color: @text-color; // This is for circle text color, should be renamed better
+@progress-circle-text-font-size: 1em;
// Menu
// ---
@menu-inline-toplevel-item-height: 40px;
diff --git a/components/vc-progress/index.js b/components/vc-progress/index.ts
similarity index 62%
rename from components/vc-progress/index.js
rename to components/vc-progress/index.ts
index 5dc2fdf679..199a021db2 100644
--- a/components/vc-progress/index.js
+++ b/components/vc-progress/index.ts
@@ -1,5 +1,5 @@
// based on rc-progress 2.5.2
-import Progress, { Line, Circle } from './src/';
+import Progress, { Line, Circle } from './src';
export { Line, Circle };
diff --git a/components/vc-progress/src/Circle.js b/components/vc-progress/src/Circle.js
deleted file mode 100644
index 8b951253df..0000000000
--- a/components/vc-progress/src/Circle.js
+++ /dev/null
@@ -1,191 +0,0 @@
-import PropTypes, { withUndefined } from '../../_util/vue-types';
-import { initDefaultProps } from '../../_util/props-util';
-import enhancer from './enhancer';
-import { propTypes, defaultProps } from './types';
-import { defineComponent } from 'vue';
-
-const circlePropTypes = {
- ...propTypes,
- gapPosition: PropTypes.oneOf(['top', 'bottom', 'left', 'right']),
- gapDegree: withUndefined(
- PropTypes.oneOfType([PropTypes.number, PropTypes.string, PropTypes.looseBool]),
- ),
-};
-
-const circleDefaultProps = {
- ...defaultProps,
- gapPosition: 'top',
-};
-
-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;
- let beginPositionY = -radius;
- let endPositionX = 0;
- let endPositionY = -2 * radius;
- switch (gapPosition) {
- case 'left':
- beginPositionX = -radius;
- beginPositionY = 0;
- endPositionX = 2 * radius;
- endPositionY = 0;
- break;
- case 'right':
- beginPositionX = radius;
- beginPositionY = 0;
- endPositionX = -2 * radius;
- endPositionY = 0;
- break;
- case 'bottom':
- beginPositionY = radius;
- endPositionY = 2 * radius;
- break;
- default:
- }
- const pathString = `M 50,50 m ${beginPositionX},${beginPositionY}
- a ${radius},${radius} 0 1 1 ${endPositionX},${-endPositionY}
- a ${radius},${radius} 0 1 1 ${-endPositionX},${endPositionY}`;
- const len = Math.PI * 2 * radius;
-
- const pathStyle = {
- stroke: strokeColor,
- strokeDasharray: `${(percent / 100) * (len - gapDegree)}px ${len}px`,
- strokeDashoffset: `-${gapDegree / 2 + (offset / 100) * (len - gapDegree)}px`,
- transition:
- 'stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s', // eslint-disable-line
- };
-
- return {
- pathString,
- pathStyle,
- };
-}
-
-const Circle = defineComponent({
- name: 'Circle',
- props: initDefaultProps(circlePropTypes, circleDefaultProps),
- created() {
- this.paths = {};
- this.gradientId = gradientSeed;
- gradientSeed += 1;
- },
- methods: {
- getStokeList() {
- const {
- prefixCls,
- percent,
- strokeColor,
- strokeWidth,
- strokeLinecap,
- gapDegree,
- gapPosition,
- } = this.$props;
- 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,
- color,
- strokeWidth,
- gapDegree,
- gapPosition,
- );
-
- stackPtg += ptg;
-
- const pathProps = {
- key: index,
- d: pathString,
- stroke,
- 'stroke-linecap': strokeLinecap,
- 'stroke-width': strokeWidth,
- opacity: ptg === 0 ? 0 : 1,
- 'fill-opacity': '0',
- class: `${prefixCls}-circle-path`,
- style: pathStyle,
- };
- return (this.paths[index] = c)} {...pathProps} />;
- });
- },
- },
-
- render() {
- const {
- prefixCls,
- strokeWidth,
- trailWidth,
- gapDegree,
- gapPosition,
- trailColor,
- strokeLinecap,
- 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]',
- );
- const pathFirst = {
- d: pathString,
- stroke: trailColor,
- 'stroke-linecap': strokeLinecap,
- 'stroke-width': trailWidth || strokeWidth,
- 'fill-opacity': '0',
- class: `${prefixCls}-circle-trail`,
- style: pathStyle,
- };
-
- return (
-
- );
- },
-});
-
-export default enhancer(Circle);
diff --git a/components/vc-progress/src/Circle.tsx b/components/vc-progress/src/Circle.tsx
new file mode 100644
index 0000000000..abb5c7cfbf
--- /dev/null
+++ b/components/vc-progress/src/Circle.tsx
@@ -0,0 +1,174 @@
+import { useTransitionDuration, defaultProps } from './common';
+import { propTypes, GapPositionType } from './types';
+import { computed, defineComponent, ref } from 'vue';
+import initDefaultProps from '../../_util/props-util/initDefaultProps';
+
+let gradientSeed = 0;
+
+function stripPercentToNumber(percent: string) {
+ return +percent.replace('%', '');
+}
+
+function toArray(value: any) {
+ return Array.isArray(value) ? value : [value];
+}
+
+function getPathStyles(
+ offset: number,
+ percent: number,
+ strokeColor: string,
+ strokeWidth: number,
+ gapDegree = 0,
+ gapPosition: GapPositionType,
+) {
+ const radius = 50 - strokeWidth / 2;
+ let beginPositionX = 0;
+ let beginPositionY = -radius;
+ let endPositionX = 0;
+ let endPositionY = -2 * radius;
+ switch (gapPosition) {
+ case 'left':
+ beginPositionX = -radius;
+ beginPositionY = 0;
+ endPositionX = 2 * radius;
+ endPositionY = 0;
+ break;
+ case 'right':
+ beginPositionX = radius;
+ beginPositionY = 0;
+ endPositionX = -2 * radius;
+ endPositionY = 0;
+ break;
+ case 'bottom':
+ beginPositionY = radius;
+ endPositionY = 2 * radius;
+ break;
+ default:
+ }
+ const pathString = `M 50,50 m ${beginPositionX},${beginPositionY}
+ a ${radius},${radius} 0 1 1 ${endPositionX},${-endPositionY}
+ a ${radius},${radius} 0 1 1 ${-endPositionX},${endPositionY}`;
+ const len = Math.PI * 2 * radius;
+
+ const pathStyle = {
+ stroke: strokeColor,
+ strokeDasharray: `${(percent / 100) * (len - gapDegree)}px ${len}px`,
+ strokeDashoffset: `-${gapDegree / 2 + (offset / 100) * (len - gapDegree)}px`,
+ transition:
+ 'stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s', // eslint-disable-line
+ };
+
+ return {
+ pathString,
+ pathStyle,
+ };
+}
+
+export default defineComponent({
+ name: 'VCCircle',
+ props: initDefaultProps(propTypes, defaultProps),
+ setup(props) {
+ gradientSeed += 1;
+ const gradientId = ref(gradientSeed);
+ const percentList = computed(() => toArray(props.percent));
+ const strokeColorList = computed(() => toArray(props.strokeColor));
+
+ const paths = useTransitionDuration(percentList);
+
+ const getStokeList = () => {
+ const { prefixCls, strokeWidth, strokeLinecap, gapDegree, gapPosition } = props;
+
+ let stackPtg = 0;
+ return percentList.value.map((ptg, index) => {
+ const color =
+ strokeColorList.value[index] || strokeColorList.value[strokeColorList.value.length - 1];
+ const stroke =
+ Object.prototype.toString.call(color) === '[object Object]'
+ ? `url(#${prefixCls}-gradient-${gradientId.value})`
+ : '';
+ const { pathString, pathStyle } = getPathStyles(
+ stackPtg,
+ ptg,
+ color,
+ strokeWidth,
+ gapDegree,
+ gapPosition,
+ );
+
+ stackPtg += ptg;
+
+ const pathProps = {
+ key: index,
+ d: pathString,
+ stroke,
+ 'stroke-linecap': strokeLinecap,
+ 'stroke-width': strokeWidth,
+ opacity: ptg === 0 ? 0 : 1,
+ 'fill-opacity': '0',
+ class: `${prefixCls}-circle-path`,
+ style: pathStyle,
+ };
+ return (paths.value[index].value = c)} {...pathProps} />;
+ });
+ };
+
+ return () => {
+ const {
+ prefixCls,
+ strokeWidth,
+ trailWidth,
+ gapDegree,
+ gapPosition,
+ trailColor,
+ strokeLinecap,
+ strokeColor,
+ ...restProps
+ } = props;
+ const { pathString, pathStyle } = getPathStyles(
+ 0,
+ 100,
+ trailColor,
+ strokeWidth,
+ gapDegree,
+ gapPosition,
+ );
+ delete restProps.percent;
+ const gradient = strokeColorList.value.find(
+ color => Object.prototype.toString.call(color) === '[object Object]',
+ );
+ const pathFirst = {
+ d: pathString,
+ stroke: trailColor,
+ 'stroke-linecap': strokeLinecap,
+ 'stroke-width': trailWidth || strokeWidth,
+ 'fill-opacity': '0',
+ class: `${prefixCls}-circle-trail`,
+ style: pathStyle,
+ };
+
+ return (
+
+ );
+ };
+ },
+});
diff --git a/components/vc-progress/src/Line.js b/components/vc-progress/src/Line.js
deleted file mode 100644
index 3e881964f4..0000000000
--- a/components/vc-progress/src/Line.js
+++ /dev/null
@@ -1,84 +0,0 @@
-import { defineComponent } from 'vue';
-import { initDefaultProps } from '../../_util/props-util';
-import enhancer from './enhancer';
-import { propTypes, defaultProps } from './types';
-
-const Line = defineComponent({
- name: 'Line',
- props: initDefaultProps(propTypes, defaultProps),
- created() {
- this.paths = {};
- },
- render() {
- const {
- percent,
- prefixCls,
- strokeColor,
- strokeLinecap,
- strokeWidth,
- trailColor,
- trailWidth,
- transition,
- ...restProps
- } = this.$props;
-
- 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;
-
- const pathFirst = {
- d: pathString,
- 'stroke-linecap': strokeLinecap,
- stroke: trailColor,
- 'stroke-width': trailWidth || strokeWidth,
- 'fill-opacity': '0',
- class: `${prefixCls}-line-trail`,
- };
- return (
-
- );
- },
-});
-
-export default enhancer(Line);
diff --git a/components/vc-progress/src/Line.tsx b/components/vc-progress/src/Line.tsx
new file mode 100644
index 0000000000..d61a5280d8
--- /dev/null
+++ b/components/vc-progress/src/Line.tsx
@@ -0,0 +1,96 @@
+import { computed, defineComponent } from 'vue';
+import initDefaultProps from '../../_util/props-util/initDefaultProps';
+import { useTransitionDuration, defaultProps } from './common';
+import { propTypes } from './types';
+
+export default defineComponent({
+ name: 'Line',
+ props: initDefaultProps(propTypes, defaultProps),
+ setup(props) {
+ const percentList = computed(() => {
+ const { percent } = props;
+ return Array.isArray(percent) ? percent : [percent];
+ });
+
+ const strokeColorList = computed(() => {
+ const { strokeColor } = props;
+ return Array.isArray(strokeColor) ? strokeColor : [strokeColor];
+ });
+
+ const paths = useTransitionDuration(percentList);
+ const center = computed(() => props.strokeWidth / 2);
+ const right = computed(() => 100 - props.strokeWidth / 2);
+
+ const pathString = computed(
+ () => `M ${props.strokeLinecap === 'round' ? center.value : 0},${center.value}
+ L ${props.strokeLinecap === 'round' ? right.value : 100},${center.value}`,
+ );
+
+ const viewBoxString = computed(() => `0 0 100 ${props.strokeWidth}`);
+
+ const pathFirst = computed(() => ({
+ d: pathString.value,
+ 'stroke-linecap': props.strokeLinecap,
+ stroke: props.trailColor,
+ 'stroke-width': props.trailWidth || props.strokeWidth,
+ 'fill-opacity': '0',
+ class: `${props.prefixCls}-line-trail`,
+ }));
+
+ return () => {
+ const {
+ percent,
+ prefixCls,
+ strokeColor,
+ strokeLinecap,
+ strokeWidth,
+ trailColor,
+ trailWidth,
+ transition,
+ ...restProps
+ } = props;
+
+ delete restProps.gapPosition;
+
+ let stackPtg = 0;
+
+ return (
+
+ );
+ };
+ },
+});
diff --git a/components/vc-progress/src/common.ts b/components/vc-progress/src/common.ts
new file mode 100644
index 0000000000..334e9577c2
--- /dev/null
+++ b/components/vc-progress/src/common.ts
@@ -0,0 +1,43 @@
+import type { Ref } from 'vue';
+import { ref, onUpdated, computed } from 'vue';
+import type { ProgressProps } from './types';
+
+export const defaultProps: Partial = {
+ percent: 0,
+ prefixCls: 'vc-progress',
+ strokeColor: '#2db7f5',
+ strokeLinecap: 'round',
+ strokeWidth: 1,
+ trailColor: '#D9D9D9',
+ trailWidth: 1,
+};
+
+export const useTransitionDuration = (percentList: Ref) => {
+ const paths = computed(() => percentList.value.map(() => ref()));
+ const prevTimeStamp = ref(null);
+
+ onUpdated(() => {
+ const now = Date.now();
+ let updated = false;
+
+ Object.keys(paths.value).forEach(key => {
+ const path = paths.value[key].value;
+ if (!path) {
+ return;
+ }
+ updated = true;
+ const pathStyle = path.style;
+ pathStyle.transitionDuration = '.3s, .3s, .3s, .06s';
+
+ if (prevTimeStamp.value && now - prevTimeStamp.value < 100) {
+ pathStyle.transitionDuration = '0s, 0s';
+ }
+ });
+
+ if (updated) {
+ prevTimeStamp.value = Date.now();
+ }
+ });
+
+ return paths;
+};
diff --git a/components/vc-progress/src/enhancer.js b/components/vc-progress/src/enhancer.js
deleted file mode 100644
index 43ad4794ec..0000000000
--- a/components/vc-progress/src/enhancer.js
+++ /dev/null
@@ -1,30 +0,0 @@
-function enhancer(Component) {
- return {
- ...Component,
- updated() {
- 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();
- }
- },
- };
-}
-
-export default enhancer;
diff --git a/components/vc-progress/src/index.js b/components/vc-progress/src/index.ts
similarity index 53%
rename from components/vc-progress/src/index.js
rename to components/vc-progress/src/index.ts
index 01fb4abd79..e6e5727860 100644
--- a/components/vc-progress/src/index.js
+++ b/components/vc-progress/src/index.ts
@@ -1,7 +1,8 @@
import Line from './Line';
import Circle from './Circle';
+import type { ProgressProps } from './types';
-export { Line, Circle };
+export { Line, Circle, ProgressProps };
export default {
Line,
diff --git a/components/vc-progress/src/types.js b/components/vc-progress/src/types.js
deleted file mode 100644
index f027d27d29..0000000000
--- a/components/vc-progress/src/types.js
+++ /dev/null
@@ -1,30 +0,0 @@
-import PropTypes from '../../_util/vue-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/components/vc-progress/src/types.ts b/components/vc-progress/src/types.ts
new file mode 100644
index 0000000000..474ed7970f
--- /dev/null
+++ b/components/vc-progress/src/types.ts
@@ -0,0 +1,31 @@
+import type { PropType, ExtractPropTypes } from 'vue';
+import PropTypes from '../../_util/vue-types';
+
+export type StrokeColorType = string | string[] | object;
+
+export type GapPositionType = 'top' | 'right' | 'bottom' | 'left';
+
+export type StrokeLinecapType = 'round' | 'butt' | 'square';
+
+export const propTypes = {
+ gapDegree: PropTypes.number,
+ gapPosition: {
+ type: String as PropType,
+ },
+ percent: {
+ type: [Array, Number] as PropType,
+ },
+ prefixCls: PropTypes.string,
+ strokeColor: {
+ type: [Object, String, Array] as PropType,
+ },
+ strokeLinecap: {
+ type: String as PropType,
+ },
+ strokeWidth: PropTypes.number,
+ trailColor: PropTypes.string,
+ trailWidth: PropTypes.number,
+ transition: PropTypes.string,
+};
+
+export type ProgressProps = Partial>;
From 01fb7f156f94e35b1cb08a3977f8ee1a73298c07 Mon Sep 17 00:00:00 2001
From: tangjinzhou <415800467@qq.com>
Date: Mon, 12 Jul 2021 16:39:54 +0800
Subject: [PATCH 13/28] refactor: progress
---
components/_util/hooks/useRef.ts | 6 +-
components/progress/Circle.tsx | 47 ++----------
components/progress/Line.tsx | 13 ++--
.../__snapshots__/index.test.js.snap | 12 +++
components/progress/__tests__/index.test.js | 24 +++---
components/progress/progress.tsx | 45 +++++------
components/progress/props.ts | 2 -
components/progress/style/index.less | 6 +-
.../progress/style/{index.ts => index.tsx} | 0
components/progress/utils.ts | 15 ++--
components/vc-progress/index.ts | 5 +-
components/vc-progress/src/Circle.tsx | 6 +-
components/vc-progress/src/Line.tsx | 76 +++++++++++--------
components/vc-progress/src/common.ts | 9 +--
package.json | 1 +
v2-doc | 2 +-
16 files changed, 133 insertions(+), 136 deletions(-)
rename components/progress/style/{index.ts => index.tsx} (100%)
diff --git a/components/_util/hooks/useRef.ts b/components/_util/hooks/useRef.ts
index 5033e9ea4e..86f6512ecd 100644
--- a/components/_util/hooks/useRef.ts
+++ b/components/_util/hooks/useRef.ts
@@ -2,9 +2,9 @@ import type { Ref } from 'vue';
import { onBeforeUpdate, ref } from 'vue';
export type UseRef = [(el: any, key: string | number) => void, Ref];
-
+export type Refs = Record;
export const useRef = (): UseRef => {
- const refs = ref({});
+ const refs = ref({});
const setRef = (el: any, key: string | number) => {
refs.value[key] = el;
};
@@ -13,3 +13,5 @@ export const useRef = (): UseRef => {
});
return [setRef, refs];
};
+
+export default useRef;
diff --git a/components/progress/Circle.tsx b/components/progress/Circle.tsx
index 8d8ac2eb4d..c2265d354e 100644
--- a/components/progress/Circle.tsx
+++ b/components/progress/Circle.tsx
@@ -1,5 +1,6 @@
import type { CSSProperties, ExtractPropTypes } from 'vue';
import { computed, defineComponent } from 'vue';
+import { presetPrimaryColors } from '@ant-design/colors';
import { Circle as VCCircle } from '../vc-progress';
import { getSuccessPercent, validProgress } from './utils';
import { progressProps } from './props';
@@ -12,39 +13,9 @@ const circleProps = {
};
export type CircleProps = Partial>;
-const statusColorMap = {
- normal: '#108ee9',
- exception: '#ff5500',
- success: '#87d068',
-};
-
-function getPercentage(
- percent: CircleProps['percent'],
- success: CircleProps['success'],
- successPercent: CircleProps['successPercent'],
-) {
- const ptg = validProgress(percent);
- const realSuccessPercent = getSuccessPercent(success, successPercent);
- if (!realSuccessPercent) {
- return ptg;
- }
- return [
- validProgress(realSuccessPercent),
- validProgress(ptg - validProgress(realSuccessPercent)),
- ];
-}
-
-function getStrokeColor(
- success: CircleProps['success'],
- strokeColor: CircleProps['strokeColor'],
- successPercent: CircleProps['successPercent'],
-) {
- const color = strokeColor || null;
- const realSuccessPercent = getSuccessPercent(success, successPercent);
- if (!realSuccessPercent) {
- return color;
- }
- return [statusColorMap.success, color];
+function getPercentage({ percent, success, successPercent }: CircleProps) {
+ const realSuccessPercent = validProgress(getSuccessPercent({ success, successPercent }));
+ return [realSuccessPercent, validProgress(validProgress(percent) - realSuccessPercent)];
}
export default defineComponent({
@@ -77,14 +48,10 @@ export default defineComponent({
);
// using className to style stroke color
- const strokeColor = computed(() =>
- getStrokeColor(props.success, props.strokeColor, props.successPercent),
- );
- const percent = computed(() =>
- getPercentage(props.percent, props.success, props.successPercent),
- );
+ const strokeColor = computed(() => [presetPrimaryColors.green, props.strokeColor || null]);
+ const percent = computed(() => getPercentage(props));
const isGradient = computed(
- () => Object.prototype.toString.call(strokeColor.value) === '[object Object]',
+ () => Object.prototype.toString.call(props.strokeColor) === '[object Object]',
);
const wrapperClassName = computed(() => ({
diff --git a/components/progress/Line.tsx b/components/progress/Line.tsx
index ca01f86719..df9bfe42c6 100644
--- a/components/progress/Line.tsx
+++ b/components/progress/Line.tsx
@@ -69,6 +69,7 @@ export const handleGradient = (strokeColor: ProgressGradient, directionConfig: D
export default defineComponent({
props: lineProps,
+ name: 'Line',
setup(props, { slots }) {
const backgroundProps = computed(() => {
const { strokeColor, direction } = props;
@@ -98,7 +99,7 @@ export default defineComponent({
});
const successPercent = computed(() => {
- return getSuccessPercent(props.success, props.successPercent);
+ return getSuccessPercent(props);
});
const successPercentStyle = computed(() => {
const { strokeWidth, size, strokeLinecap, success } = props;
@@ -110,18 +111,14 @@ export default defineComponent({
};
});
- const successSegment = computed(() =>
- successPercent.value !== undefined ? (
-
- ) : null,
- );
-
return () => (
<>
- {successSegment.value}
+ {successPercent.value !== undefined ? (
+
+ ) : null}
{slots.default?.()}
diff --git a/components/progress/__tests__/__snapshots__/index.test.js.snap b/components/progress/__tests__/__snapshots__/index.test.js.snap
index cc19fbf18d..0f52246db2 100644
--- a/components/progress/__tests__/__snapshots__/index.test.js.snap
+++ b/components/progress/__tests__/__snapshots__/index.test.js.snap
@@ -10,6 +10,9 @@ exports[`Progress render dashboard 295 gapDegree 1`] = `
+
0%