diff --git a/components/progress/Circle.tsx b/components/progress/Circle.tsx index 0bbaa5db3..a7a6d81a3 100644 --- a/components/progress/Circle.tsx +++ b/components/progress/Circle.tsx @@ -1,13 +1,21 @@ import type { CSSProperties } from 'vue'; import { computed, defineComponent } from 'vue'; import { Circle as VCCircle } from '../vc-progress'; -import { getPercentage, getStrokeColor } from './utils'; -import type { ProgressProps } from './props'; +import { getPercentage, getSize, getStrokeColor } from './utils'; +import type { ProgressProps, ProgressGradient } from './props'; import { progressProps } from './props'; import { initDefaultProps } from '../_util/props-util'; import Tooltip from '../tooltip'; +import { anyType } from '../_util/type'; -export type CircleProps = ProgressProps; +export interface CircleProps extends ProgressProps { + strokeColor?: string | ProgressGradient; +} + +export const circleProps = () => ({ + ...progressProps(), + strokeColor: anyType(), +}); const CIRCLE_MIN_STROKE_WIDTH = 3; @@ -17,11 +25,14 @@ export default defineComponent({ compatConfig: { MODE: 3 }, name: 'Circle', inheritAttrs: false, - props: initDefaultProps(progressProps(), { - width: 120, + props: initDefaultProps(circleProps(), { trailColor: null as unknown as string, }), setup(props, { slots }) { + const originWidth = computed(() => props.width || 120); + const mergedSize = computed(() => props.size ?? [originWidth.value, originWidth.value]); + + const sizeRef = computed(() => getSize(mergedSize.value as ProgressProps['size'], 'circle')); const gapDeg = computed(() => { // Support gapDeg = 0 when type = 'dashboard' if (props.gapDegree || props.gapDegree === 0) { @@ -34,16 +45,15 @@ export default defineComponent({ }); const circleStyle = computed(() => { - const circleSize = props.width; return { - width: typeof circleSize === 'number' ? `${circleSize}px` : circleSize, - height: typeof circleSize === 'number' ? `${circleSize}px` : circleSize, - fontSize: `${circleSize * 0.15 + 6}px`, + width: `${sizeRef.value.width}px`, + height: `${sizeRef.value.height}px`, + fontSize: `${sizeRef.value.width * 0.15 + 6}px`, }; }); const circleWidth = computed( - () => props.strokeWidth ?? Math.max(getMinPercent(props.width), 6), + () => props.strokeWidth ?? Math.max(getMinPercent(sizeRef.value.width), 6), ); const gapPos = computed( () => props.gapPosition || (props.type === 'dashboard' && 'bottom') || undefined, @@ -78,8 +88,10 @@ export default defineComponent({ ); return (
- {props.width <= 20 ? ( - {circleContent} + {sizeRef.value.width <= 20 ? ( + + {circleContent} + ) : ( <> {circleContent} diff --git a/components/progress/Line.tsx b/components/progress/Line.tsx index f46a7d20d..0b02642e4 100644 --- a/components/progress/Line.tsx +++ b/components/progress/Line.tsx @@ -2,13 +2,15 @@ import type { CSSProperties, ExtractPropTypes, PropType } from 'vue'; import { presetPrimaryColors } from '@ant-design/colors'; import { computed, defineComponent } from 'vue'; import type { Direction } from '../config-provider'; -import type { StringGradients, ProgressGradient } from './props'; +import type { StringGradients, ProgressGradient, ProgressSize } from './props'; import { progressProps } from './props'; -import { getSuccessPercent, validProgress } from './utils'; +import { getSize, getSuccessPercent, validProgress } from './utils'; +import devWarning from '../vc-util/devWarning'; +import { anyType } from '../_util/type'; export const lineProps = () => ({ ...progressProps(), - prefixCls: String, + strokeColor: anyType(), direction: { type: String as PropType, }, @@ -84,6 +86,8 @@ export default defineComponent({ backgroundColor: strokeColor as string, }; }); + const borderRadius = + props.strokeLinecap === 'square' || props.strokeLinecap === 'butt' ? 0 : undefined; const trailStyle = computed(() => props.trailColor @@ -93,13 +97,29 @@ export default defineComponent({ : undefined, ); + const mergedSize = computed( + () => props.size ?? [-1, props.strokeWidth || (props.size === 'small' ? 6 : 8)], + ); + + const sizeRef = computed(() => + getSize(mergedSize.value as ProgressSize, 'line', { strokeWidth: props.strokeWidth }), + ); + + if (process.env.NODE_ENV !== 'production') { + devWarning( + 'strokeWidth' in props, + 'Progress', + '`strokeWidth` is deprecated. Please use `size` instead.', + ); + } + const percentStyle = computed(() => { - const { percent, strokeWidth, strokeLinecap, size } = props; + const { percent } = props; return { width: `${validProgress(percent)}%`, - height: `${strokeWidth || (size === 'small' ? 6 : 8)}px`, - borderRadius: strokeLinecap === 'square' ? 0 : undefined, - ...(backgroundProps.value as any), + height: `${sizeRef.value.height}px`, + borderRadius, + ...backgroundProps.value, }; }); @@ -107,18 +127,23 @@ export default defineComponent({ return getSuccessPercent(props); }); const successPercentStyle = computed(() => { - const { strokeWidth, size, strokeLinecap, success } = props; + const { success } = props; return { width: `${validProgress(successPercent.value)}%`, - height: `${strokeWidth || (size === 'small' ? 6 : 8)}px`, - borderRadius: strokeLinecap === 'square' ? 0 : undefined, + height: `${sizeRef.value.height}px`, + borderRadius, backgroundColor: success?.strokeColor, }; }); + const outerStyle: CSSProperties = { + width: sizeRef.value.width < 0 ? '100%' : sizeRef.value.width, + height: `${sizeRef.value.height}px`, + }; + return () => ( <> -
+
{successPercent.value !== undefined ? ( diff --git a/components/progress/Steps.tsx b/components/progress/Steps.tsx index 322673fa4..c67c9d155 100644 --- a/components/progress/Steps.tsx +++ b/components/progress/Steps.tsx @@ -1,8 +1,10 @@ import type { ExtractPropTypes, PropType } from 'vue'; import { computed, defineComponent } from 'vue'; import type { VueNode } from '../_util/type'; +import PropTypes from '../_util/vue-types'; import type { ProgressSize } from './props'; import { progressProps } from './props'; +import { getSize } from './utils'; export const stepsProps = () => ({ ...progressProps(), @@ -10,11 +12,11 @@ export const stepsProps = () => ({ size: { type: String as PropType, }, - strokeColor: String, + strokeColor: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]), trailColor: String, }); -export type StepsProps = Partial>; +export type StepsProps = Partial>>; export default defineComponent({ compatConfig: { MODE: 3 }, @@ -22,13 +24,22 @@ export default defineComponent({ props: stepsProps(), setup(props, { slots }) { const current = computed(() => Math.round(props.steps * ((props.percent || 0) / 100))); - const stepWidth = computed(() => (props.size === 'small' ? 2 : 14)); + const mergedSize = computed( + () => props.size ?? [props.size === 'small' ? 2 : 14, props.strokeWidth || 8], + ); + const sizeRef = computed(() => + getSize(mergedSize.value as ProgressSize, 'step', { + steps: props.steps, + strokeWidth: props.strokeWidth || 8, + }), + ); const styledSteps = computed(() => { - const { steps, strokeWidth = 8, strokeColor, trailColor, prefixCls } = props; + const { steps, strokeColor, trailColor, prefixCls } = props; const temp: VueNode[] = []; for (let i = 0; i < steps; i += 1) { + const color = Array.isArray(strokeColor) ? strokeColor[i] : strokeColor; const cls = { [`${prefixCls}-steps-item`]: true, [`${prefixCls}-steps-item-active`]: i <= current.value - 1, @@ -38,9 +49,9 @@ export default defineComponent({ key={i} class={cls} style={{ - backgroundColor: i <= current.value - 1 ? strokeColor : trailColor, - width: `${stepWidth.value}px`, - height: `${strokeWidth}px`, + backgroundColor: i <= current.value - 1 ? color : trailColor, + width: `${sizeRef.value.width / steps}px`, + height: `${sizeRef.value.height}px`, }} />, ); diff --git a/components/progress/__tests__/__snapshots__/demo.test.js.snap b/components/progress/__tests__/__snapshots__/demo.test.js.snap index de03a8714..7f8cbea49 100644 --- a/components/progress/__tests__/__snapshots__/demo.test.js.snap +++ b/components/progress/__tests__/__snapshots__/demo.test.js.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`renders ./components/progress/demo/circle.vue correctly 1`] = ` -
+
75%
-
+
-
+
+
0%
-
+
+
+`; + +exports[`renders ./components/progress/demo/circle-micro.vue correctly 1`] = ` +
+
+
+ +
+
代码发布
`; exports[`renders ./components/progress/demo/circle-mini.vue correctly 1`] = ` -
+
30%
-
+
-
+
+
-
+
+
0%
-
+
`; exports[`renders ./components/progress/demo/format.vue correctly 1`] = `
-
+
75 Days
-
+
Done
-
+
-
+
+
99.9%
-
-
+
+
99.9%
-
-
- - - - - - - - - - 90%
-
-
+
@@ -240,7 +237,26 @@ exports[`renders ./components/progress/demo/gradient-line.vue correctly 1`] = ` a 47,47 0 1 1 0,-94" stroke-linecap="round" stroke-width="6" fill-opacity="0" class="ant-progress-circle-trail" style="stroke-dasharray: 295.3097094374406px 295.3097094374406px; stroke-dashoffset: -0px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;"> + a 47,47 0 1 1 0,-94" stroke="url(#ant-progress-gradient-13)" stroke-linecap="round" stroke-width="6" opacity="1" fill-opacity="0" class="ant-progress-circle-path" style="stroke: [object Object]; stroke-dasharray: 265.77873849369655px 295.3097094374406px; stroke-dashoffset: -0px; transition: stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s, opacity .3s ease 0s;"> + + 90%
+
+
+
+ + + + + + + + @@ -250,40 +266,40 @@ exports[`renders ./components/progress/demo/gradient-line.vue correctly 1`] = ` `; exports[`renders ./components/progress/demo/line.vue correctly 1`] = ` -
-
+
+
30%
-
-
+
+
50%
-
-
+
+
-
-
+
+
-
-
+
+
@@ -295,32 +311,32 @@ exports[`renders ./components/progress/demo/line.vue correctly 1`] = ` exports[`renders ./components/progress/demo/line-mini.vue correctly 1`] = `
-
-
+
+
30%
-
-
+
+
50%
-
-
+
+
-
-
+
+
@@ -332,15 +348,15 @@ exports[`renders ./components/progress/demo/line-mini.vue correctly 1`] = ` exports[`renders ./components/progress/demo/linecap.vue correctly 1`] = `
-
-
+
+
75%
-
+
75%
-
+
-
+
+
@@ -383,7 +399,7 @@ exports[`renders ./components/progress/demo/segment.vue correctly 1`] = `
60%
-
+
60%
-
+
+
+
+
+
+
+ +
+
50% +
+
+ +
+
+
+
+
+ +
+
50% +
+
+ +
+
+
+
+
+ +
+
50% +
+
+ +


+
+
+
+
+ + + + + 50%
+
+
+ +
+
+
+ + + + + 50%
+
+
+ +
+
+
+ +
+
+
+ +


+
+
+
+
+ + + + + 50%
+
+
+ +
+
+
+ + + + + 50%
+
+
+ +
+
+
+ +
+
+
+ +


+
+
+
+
+
+
+
50% +
+
+
+ +
+
+
+
+
+
50% +
+
+
+ +
+
+
+
+
+
50% +
+
+
+ +
+
+
+
+
+
50% +
+
+
+ +
+
+`; + exports[`renders ./components/progress/demo/steps.vue correctly 1`] = ` -
+
@@ -424,7 +622,7 @@ exports[`renders ./components/progress/demo/steps.vue correctly 1`] = `

-
+
@@ -434,7 +632,7 @@ exports[`renders ./components/progress/demo/steps.vue correctly 1`] = `

-
+
@@ -443,4 +641,14 @@ exports[`renders ./components/progress/demo/steps.vue correctly 1`] = `
+
+
+
+
+
+
+
+
60% +
+
`; diff --git a/components/progress/__tests__/__snapshots__/index.test.js.snap b/components/progress/__tests__/__snapshots__/index.test.js.snap index 0f52246db..2869cf370 100644 --- a/components/progress/__tests__/__snapshots__/index.test.js.snap +++ b/components/progress/__tests__/__snapshots__/index.test.js.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Progress render dashboard 295 gapDegree 1`] = ` -
+
+
+
-
+
+
@@ -63,8 +63,8 @@ exports[`Progress render format 1`] = ` `; exports[`Progress render negative progress 1`] = ` -
-
+
+
@@ -74,8 +74,8 @@ exports[`Progress render negative progress 1`] = ` `; exports[`Progress render negative successPercent 1`] = ` -
-
+
+
@@ -85,8 +85,8 @@ exports[`Progress render negative successPercent 1`] = ` `; exports[`Progress render normal progress 1`] = ` -
-
+
+
@@ -96,8 +96,8 @@ exports[`Progress render normal progress 1`] = ` `; exports[`Progress render out-of-range progress 1`] = ` -
-
+
+
@@ -107,8 +107,8 @@ exports[`Progress render out-of-range progress 1`] = ` `; exports[`Progress render out-of-range progress with info 1`] = ` -
-
+
+
@@ -118,7 +118,7 @@ exports[`Progress render out-of-range progress with info 1`] = ` `; exports[`Progress render strokeColor 1`] = ` -
+
-
+
+
@@ -146,8 +146,8 @@ exports[`Progress render strokeColor 2`] = ` `; exports[`Progress render strokeColor 3`] = ` -
-
+
+
@@ -157,8 +157,8 @@ exports[`Progress render strokeColor 3`] = ` `; exports[`Progress render successColor progress 1`] = ` -
-
+
+
@@ -168,8 +168,8 @@ exports[`Progress render successColor progress 1`] = ` `; exports[`Progress render trailColor progress 1`] = ` -
-
+
+
@@ -179,7 +179,7 @@ exports[`Progress render trailColor progress 1`] = ` `; exports[`Progress should support steps 1`] = ` -
+
diff --git a/components/progress/demo/circle-micro.vue b/components/progress/demo/circle-micro.vue new file mode 100644 index 000000000..ab848b6fe --- /dev/null +++ b/components/progress/demo/circle-micro.vue @@ -0,0 +1,32 @@ + +--- +order: 13 +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. + + + + + diff --git a/components/progress/demo/circle-mini.vue b/components/progress/demo/circle-mini.vue index dfedca8b2..43e42c67a 100644 --- a/components/progress/demo/circle-mini.vue +++ b/components/progress/demo/circle-mini.vue @@ -17,7 +17,7 @@ A smaller circular progress bar. diff --git a/components/progress/demo/index.vue b/components/progress/demo/index.vue index 03f53f046..90a81776a 100644 --- a/components/progress/demo/index.vue +++ b/components/progress/demo/index.vue @@ -4,6 +4,7 @@ + @@ -12,6 +13,7 @@ +