Skip to content

Commit 7db4265

Browse files
authored
feat(Progress): enhance size prop and add variants (#6409)
* refactor(progress): Progress size and add variants * feat(progress): add `getsize` * refactor(progress): Progress size and add variants * chore(progress): update props type * chore(progress): update props type * feat(progress): update demo * feat(progress): update docs * test(progress): update test snap * fix(Circle): Merging classes * test(progress): update test snap * feat(progress): add size demo * test(progress): add size snapshot * chore(Progress): reback Circle svg class change
1 parent 8a3ed32 commit 7db4265

16 files changed

+573
-161
lines changed

components/progress/Circle.tsx

+24-12
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
11
import type { CSSProperties } from 'vue';
22
import { computed, defineComponent } from 'vue';
33
import { Circle as VCCircle } from '../vc-progress';
4-
import { getPercentage, getStrokeColor } from './utils';
5-
import type { ProgressProps } from './props';
4+
import { getPercentage, getSize, getStrokeColor } from './utils';
5+
import type { ProgressProps, ProgressGradient } from './props';
66
import { progressProps } from './props';
77
import { initDefaultProps } from '../_util/props-util';
88
import Tooltip from '../tooltip';
9+
import { anyType } from '../_util/type';
910

10-
export type CircleProps = ProgressProps;
11+
export interface CircleProps extends ProgressProps {
12+
strokeColor?: string | ProgressGradient;
13+
}
14+
15+
export const circleProps = () => ({
16+
...progressProps(),
17+
strokeColor: anyType<string | ProgressGradient>(),
18+
});
1119

1220
const CIRCLE_MIN_STROKE_WIDTH = 3;
1321

@@ -17,11 +25,14 @@ export default defineComponent({
1725
compatConfig: { MODE: 3 },
1826
name: 'Circle',
1927
inheritAttrs: false,
20-
props: initDefaultProps(progressProps(), {
21-
width: 120,
28+
props: initDefaultProps(circleProps(), {
2229
trailColor: null as unknown as string,
2330
}),
2431
setup(props, { slots }) {
32+
const originWidth = computed(() => props.width || 120);
33+
const mergedSize = computed(() => props.size ?? [originWidth.value, originWidth.value]);
34+
35+
const sizeRef = computed(() => getSize(mergedSize.value as ProgressProps['size'], 'circle'));
2536
const gapDeg = computed(() => {
2637
// Support gapDeg = 0 when type = 'dashboard'
2738
if (props.gapDegree || props.gapDegree === 0) {
@@ -34,16 +45,15 @@ export default defineComponent({
3445
});
3546

3647
const circleStyle = computed<CSSProperties>(() => {
37-
const circleSize = props.width;
3848
return {
39-
width: typeof circleSize === 'number' ? `${circleSize}px` : circleSize,
40-
height: typeof circleSize === 'number' ? `${circleSize}px` : circleSize,
41-
fontSize: `${circleSize * 0.15 + 6}px`,
49+
width: `${sizeRef.value.width}px`,
50+
height: `${sizeRef.value.height}px`,
51+
fontSize: `${sizeRef.value.width * 0.15 + 6}px`,
4252
};
4353
});
4454

4555
const circleWidth = computed(
46-
() => props.strokeWidth ?? Math.max(getMinPercent(props.width), 6),
56+
() => props.strokeWidth ?? Math.max(getMinPercent(sizeRef.value.width), 6),
4757
);
4858
const gapPos = computed(
4959
() => props.gapPosition || (props.type === 'dashboard' && 'bottom') || undefined,
@@ -78,8 +88,10 @@ export default defineComponent({
7888
);
7989
return (
8090
<div class={wrapperClassName.value} style={circleStyle.value}>
81-
{props.width <= 20 ? (
82-
<Tooltip v-slots={{ title: slots.default }}>{circleContent}</Tooltip>
91+
{sizeRef.value.width <= 20 ? (
92+
<Tooltip v-slots={{ title: slots.default }}>
93+
<span>{circleContent}</span>
94+
</Tooltip>
8395
) : (
8496
<>
8597
{circleContent}

components/progress/Line.tsx

+36-11
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ import type { CSSProperties, ExtractPropTypes, PropType } from 'vue';
22
import { presetPrimaryColors } from '@ant-design/colors';
33
import { computed, defineComponent } from 'vue';
44
import type { Direction } from '../config-provider';
5-
import type { StringGradients, ProgressGradient } from './props';
5+
import type { StringGradients, ProgressGradient, ProgressSize } from './props';
66
import { progressProps } from './props';
7-
import { getSuccessPercent, validProgress } from './utils';
7+
import { getSize, getSuccessPercent, validProgress } from './utils';
8+
import devWarning from '../vc-util/devWarning';
9+
import { anyType } from '../_util/type';
810

911
export const lineProps = () => ({
1012
...progressProps(),
11-
prefixCls: String,
13+
strokeColor: anyType<string | ProgressGradient>(),
1214
direction: {
1315
type: String as PropType<Direction>,
1416
},
@@ -84,6 +86,8 @@ export default defineComponent({
8486
backgroundColor: strokeColor as string,
8587
};
8688
});
89+
const borderRadius =
90+
props.strokeLinecap === 'square' || props.strokeLinecap === 'butt' ? 0 : undefined;
8791

8892
const trailStyle = computed<CSSProperties>(() =>
8993
props.trailColor
@@ -93,32 +97,53 @@ export default defineComponent({
9397
: undefined,
9498
);
9599

100+
const mergedSize = computed(
101+
() => props.size ?? [-1, props.strokeWidth || (props.size === 'small' ? 6 : 8)],
102+
);
103+
104+
const sizeRef = computed(() =>
105+
getSize(mergedSize.value as ProgressSize, 'line', { strokeWidth: props.strokeWidth }),
106+
);
107+
108+
if (process.env.NODE_ENV !== 'production') {
109+
devWarning(
110+
'strokeWidth' in props,
111+
'Progress',
112+
'`strokeWidth` is deprecated. Please use `size` instead.',
113+
);
114+
}
115+
96116
const percentStyle = computed<CSSProperties>(() => {
97-
const { percent, strokeWidth, strokeLinecap, size } = props;
117+
const { percent } = props;
98118
return {
99119
width: `${validProgress(percent)}%`,
100-
height: `${strokeWidth || (size === 'small' ? 6 : 8)}px`,
101-
borderRadius: strokeLinecap === 'square' ? 0 : undefined,
102-
...(backgroundProps.value as any),
120+
height: `${sizeRef.value.height}px`,
121+
borderRadius,
122+
...backgroundProps.value,
103123
};
104124
});
105125

106126
const successPercent = computed(() => {
107127
return getSuccessPercent(props);
108128
});
109129
const successPercentStyle = computed<CSSProperties>(() => {
110-
const { strokeWidth, size, strokeLinecap, success } = props;
130+
const { success } = props;
111131
return {
112132
width: `${validProgress(successPercent.value)}%`,
113-
height: `${strokeWidth || (size === 'small' ? 6 : 8)}px`,
114-
borderRadius: strokeLinecap === 'square' ? 0 : undefined,
133+
height: `${sizeRef.value.height}px`,
134+
borderRadius,
115135
backgroundColor: success?.strokeColor,
116136
};
117137
});
118138

139+
const outerStyle: CSSProperties = {
140+
width: sizeRef.value.width < 0 ? '100%' : sizeRef.value.width,
141+
height: `${sizeRef.value.height}px`,
142+
};
143+
119144
return () => (
120145
<>
121-
<div {...attrs} class={[`${props.prefixCls}-outer`, attrs.class]}>
146+
<div {...attrs} class={[`${props.prefixCls}-outer`, attrs.class]} style={outerStyle}>
122147
<div class={`${props.prefixCls}-inner`} style={trailStyle.value}>
123148
<div class={`${props.prefixCls}-bg`} style={percentStyle.value} />
124149
{successPercent.value !== undefined ? (

components/progress/Steps.tsx

+18-7
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,45 @@
11
import type { ExtractPropTypes, PropType } from 'vue';
22
import { computed, defineComponent } from 'vue';
33
import type { VueNode } from '../_util/type';
4+
import PropTypes from '../_util/vue-types';
45
import type { ProgressSize } from './props';
56
import { progressProps } from './props';
7+
import { getSize } from './utils';
68

79
export const stepsProps = () => ({
810
...progressProps(),
911
steps: Number,
1012
size: {
1113
type: String as PropType<ProgressSize>,
1214
},
13-
strokeColor: String,
15+
strokeColor: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
1416
trailColor: String,
1517
});
1618

17-
export type StepsProps = Partial<ExtractPropTypes<typeof stepsProps>>;
19+
export type StepsProps = Partial<ExtractPropTypes<ReturnType<typeof stepsProps>>>;
1820

1921
export default defineComponent({
2022
compatConfig: { MODE: 3 },
2123
name: 'Steps',
2224
props: stepsProps(),
2325
setup(props, { slots }) {
2426
const current = computed(() => Math.round(props.steps * ((props.percent || 0) / 100)));
25-
const stepWidth = computed(() => (props.size === 'small' ? 2 : 14));
27+
const mergedSize = computed(
28+
() => props.size ?? [props.size === 'small' ? 2 : 14, props.strokeWidth || 8],
29+
);
30+
const sizeRef = computed(() =>
31+
getSize(mergedSize.value as ProgressSize, 'step', {
32+
steps: props.steps,
33+
strokeWidth: props.strokeWidth || 8,
34+
}),
35+
);
2636

2737
const styledSteps = computed(() => {
28-
const { steps, strokeWidth = 8, strokeColor, trailColor, prefixCls } = props;
38+
const { steps, strokeColor, trailColor, prefixCls } = props;
2939

3040
const temp: VueNode[] = [];
3141
for (let i = 0; i < steps; i += 1) {
42+
const color = Array.isArray(strokeColor) ? strokeColor[i] : strokeColor;
3243
const cls = {
3344
[`${prefixCls}-steps-item`]: true,
3445
[`${prefixCls}-steps-item-active`]: i <= current.value - 1,
@@ -38,9 +49,9 @@ export default defineComponent({
3849
key={i}
3950
class={cls}
4051
style={{
41-
backgroundColor: i <= current.value - 1 ? strokeColor : trailColor,
42-
width: `${stepWidth.value}px`,
43-
height: `${strokeWidth}px`,
52+
backgroundColor: i <= current.value - 1 ? color : trailColor,
53+
width: `${sizeRef.value.width / steps}px`,
54+
height: `${sizeRef.value.height}px`,
4455
}}
4556
/>,
4657
);

0 commit comments

Comments
 (0)