mirror of
https://gitee.com/ant-design-vue/ant-design-vue.git
synced 2024-12-02 12:07:54 +08:00
refactor: progress #6234
This commit is contained in:
parent
2c1afa5e72
commit
a40816880a
@ -55,6 +55,10 @@ export function booleanType(defaultVal?: any) {
|
||||
return { type: Boolean, default: defaultVal as boolean };
|
||||
}
|
||||
|
||||
export function functionType<T = () => {}>(defaultVal?: any) {
|
||||
return { type: Function as PropType<T>, default: defaultVal as T };
|
||||
}
|
||||
|
||||
export function anyType<T = any>() {
|
||||
return { validator: () => true } as unknown as { type: PropType<T> };
|
||||
}
|
||||
|
@ -1,31 +1,26 @@
|
||||
import type { CSSProperties } 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 { getPercentage, getStrokeColor } from './utils';
|
||||
import type { ProgressProps } from './props';
|
||||
import { progressProps } from './props';
|
||||
import { initDefaultProps } from '../_util/props-util';
|
||||
import Tooltip from '../tooltip';
|
||||
|
||||
export type CircleProps = ProgressProps;
|
||||
|
||||
function getPercentage({ percent, success, successPercent }: CircleProps) {
|
||||
const realSuccessPercent = validProgress(getSuccessPercent({ success, successPercent }));
|
||||
return [realSuccessPercent, validProgress(validProgress(percent) - realSuccessPercent)];
|
||||
}
|
||||
const CIRCLE_MIN_STROKE_WIDTH = 3;
|
||||
|
||||
function getStrokeColor({
|
||||
success = {},
|
||||
strokeColor,
|
||||
}: Partial<CircleProps>): (string | Record<string, string>)[] {
|
||||
const { strokeColor: successColor } = success;
|
||||
return [successColor || presetPrimaryColors.green, strokeColor || null!];
|
||||
}
|
||||
const getMinPercent = (width: number): number => (CIRCLE_MIN_STROKE_WIDTH / width) * 100;
|
||||
|
||||
export default defineComponent({
|
||||
compatConfig: { MODE: 3 },
|
||||
name: 'Circle',
|
||||
inheritAttrs: false,
|
||||
props: progressProps(),
|
||||
props: initDefaultProps(progressProps(), {
|
||||
width: 120,
|
||||
trailColor: null as unknown as string,
|
||||
}),
|
||||
setup(props, { slots }) {
|
||||
const gapDeg = computed(() => {
|
||||
// Support gapDeg = 0 when type = 'dashboard'
|
||||
@ -39,7 +34,7 @@ export default defineComponent({
|
||||
});
|
||||
|
||||
const circleStyle = computed<CSSProperties>(() => {
|
||||
const circleSize = props.width || 120;
|
||||
const circleSize = props.width;
|
||||
return {
|
||||
width: typeof circleSize === 'number' ? `${circleSize}px` : circleSize,
|
||||
height: typeof circleSize === 'number' ? `${circleSize}px` : circleSize,
|
||||
@ -47,9 +42,11 @@ export default defineComponent({
|
||||
};
|
||||
});
|
||||
|
||||
const circleWidth = computed(() => props.strokeWidth || 6);
|
||||
const circleWidth = computed(
|
||||
() => props.strokeWidth ?? Math.max(getMinPercent(props.width), 6),
|
||||
);
|
||||
const gapPos = computed(
|
||||
() => props.gapPosition || (props.type === 'dashboard' && 'bottom') || 'top',
|
||||
() => props.gapPosition || (props.type === 'dashboard' && 'bottom') || undefined,
|
||||
);
|
||||
|
||||
// using className to style stroke color
|
||||
@ -65,8 +62,8 @@ export default defineComponent({
|
||||
[`${props.prefixCls}-circle-gradient`]: isGradient.value,
|
||||
}));
|
||||
|
||||
return () => (
|
||||
<div class={wrapperClassName.value} style={circleStyle.value}>
|
||||
return () => {
|
||||
const circleContent = (
|
||||
<VCCircle
|
||||
percent={percent.value}
|
||||
strokeWidth={circleWidth.value}
|
||||
@ -78,8 +75,19 @@ export default defineComponent({
|
||||
gapDegree={gapDeg.value}
|
||||
gapPosition={gapPos.value}
|
||||
/>
|
||||
{slots.default?.()}
|
||||
</div>
|
||||
);
|
||||
);
|
||||
return (
|
||||
<div class={wrapperClassName.value} style={circleStyle.value}>
|
||||
{props.width <= 20 ? (
|
||||
<Tooltip v-slots={{ title: slots.default }}>{circleContent}</Tooltip>
|
||||
) : (
|
||||
<>
|
||||
{circleContent}
|
||||
{slots.default?.()}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
||||
|
@ -53,7 +53,10 @@ export const sortGradient = (gradients: StringGradients) => {
|
||||
* "100%": "#ffffff"
|
||||
* }
|
||||
*/
|
||||
export const handleGradient = (strokeColor: ProgressGradient, directionConfig: Direction) => {
|
||||
export const handleGradient = (
|
||||
strokeColor: ProgressGradient,
|
||||
directionConfig?: Direction,
|
||||
): CSSProperties => {
|
||||
const {
|
||||
from = presetPrimaryColors.blue,
|
||||
to = presetPrimaryColors.blue,
|
||||
@ -70,18 +73,19 @@ export const handleGradient = (strokeColor: ProgressGradient, directionConfig: D
|
||||
export default defineComponent({
|
||||
compatConfig: { MODE: 3 },
|
||||
name: 'Line',
|
||||
inheritAttrs: false,
|
||||
props: lineProps(),
|
||||
setup(props, { slots }) {
|
||||
const backgroundProps = computed(() => {
|
||||
setup(props, { slots, attrs }) {
|
||||
const backgroundProps = computed<CSSProperties>(() => {
|
||||
const { strokeColor, direction } = props;
|
||||
return strokeColor && typeof strokeColor !== 'string'
|
||||
? handleGradient(strokeColor, direction)
|
||||
: {
|
||||
background: strokeColor,
|
||||
backgroundColor: strokeColor as string,
|
||||
};
|
||||
});
|
||||
|
||||
const trailStyle = computed(() =>
|
||||
const trailStyle = computed<CSSProperties>(() =>
|
||||
props.trailColor
|
||||
? {
|
||||
backgroundColor: props.trailColor,
|
||||
@ -114,7 +118,7 @@ export default defineComponent({
|
||||
|
||||
return () => (
|
||||
<>
|
||||
<div class={`${props.prefixCls}-outer`}>
|
||||
<div {...attrs} class={[`${props.prefixCls}-outer`, attrs.class]}>
|
||||
<div class={`${props.prefixCls}-inner`} style={trailStyle.value}>
|
||||
<div class={`${props.prefixCls}-bg`} style={percentStyle.value} />
|
||||
{successPercent.value !== undefined ? (
|
||||
|
@ -2,7 +2,7 @@
|
||||
category: Components
|
||||
type: Feedback
|
||||
title: Progress
|
||||
cover: https://gw.alipayobjects.com/zos/alicdn/xqsDu4ZyR/Progress.svg
|
||||
cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*gK_4S6fDRfgAAAAAAAAAAAAADrJ8AQ/original
|
||||
---
|
||||
|
||||
Display the current progress of an operation flow.
|
||||
|
@ -3,7 +3,7 @@ category: Components
|
||||
type: 反馈
|
||||
title: Progress
|
||||
subtitle: 进度条
|
||||
cover: https://gw.alipayobjects.com/zos/alicdn/xqsDu4ZyR/Progress.svg
|
||||
cover: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*gK_4S6fDRfgAAAAAAAAAAAAADrJ8AQ/original
|
||||
---
|
||||
|
||||
展示操作的当前进度。
|
||||
|
@ -13,7 +13,6 @@ import devWarning from '../vc-util/devWarning';
|
||||
import { progressProps, progressStatuses } from './props';
|
||||
import type { VueNode } from '../_util/type';
|
||||
import useStyle from './style';
|
||||
import classNames from '../_util/classNames';
|
||||
|
||||
export default defineComponent({
|
||||
compatConfig: { MODE: 3 },
|
||||
@ -37,18 +36,6 @@ export default defineComponent({
|
||||
'Progress',
|
||||
'`successPercent` is deprecated. Please use `success.percent` instead.',
|
||||
);
|
||||
const classString = computed(() => {
|
||||
const { type, showInfo, size } = props;
|
||||
const pre = prefixCls.value;
|
||||
return {
|
||||
[hashId.value]: true,
|
||||
[pre]: true,
|
||||
[`${pre}-${(type === 'dashboard' && 'circle') || type}`]: true,
|
||||
[`${pre}-show-info`]: showInfo,
|
||||
[`${pre}-${size}`]: size,
|
||||
[`${pre}-rtl`]: direction.value === 'rtl',
|
||||
};
|
||||
});
|
||||
|
||||
const percentNumber = computed(() => {
|
||||
const { percent = 0 } = props;
|
||||
@ -61,12 +48,27 @@ export default defineComponent({
|
||||
|
||||
const progressStatus = computed(() => {
|
||||
const { status } = props;
|
||||
if (progressStatuses.indexOf(status) < 0 && percentNumber.value >= 100) {
|
||||
if (!progressStatuses.includes(status) && percentNumber.value >= 100) {
|
||||
return 'success';
|
||||
}
|
||||
return status || 'normal';
|
||||
});
|
||||
|
||||
const classString = computed(() => {
|
||||
const { type, showInfo, size } = props;
|
||||
const pre = prefixCls.value;
|
||||
return {
|
||||
[pre]: true,
|
||||
[`${pre}-inline-circle`]: type === 'circle' && props.width! <= 20,
|
||||
[`${pre}-${(type === 'dashboard' && 'circle') || type}`]: true,
|
||||
[`${pre}-status-${progressStatus.value}`]: true,
|
||||
[`${pre}-show-info`]: showInfo,
|
||||
[`${pre}-${size}`]: size,
|
||||
[`${pre}-rtl`]: direction.value === 'rtl',
|
||||
[hashId.value]: true,
|
||||
};
|
||||
});
|
||||
|
||||
const renderProcessInfo = () => {
|
||||
const { showInfo, format, type, percent, title } = props;
|
||||
const successPercent = getSuccessPercent(props);
|
||||
@ -126,12 +128,8 @@ export default defineComponent({
|
||||
);
|
||||
}
|
||||
|
||||
const classes = classNames(classString.value, {
|
||||
[`${prefixCls.value}-status-${progressStatus.value}`]: true,
|
||||
});
|
||||
|
||||
return wrapSSR(
|
||||
<div {...restAttrs} class={[classes, cls]} title={title}>
|
||||
<div role="progressbar" {...restAttrs} class={[classString.value, cls]} title={title}>
|
||||
{progress}
|
||||
</div>,
|
||||
);
|
||||
|
@ -1,45 +1,40 @@
|
||||
import PropTypes from '../_util/vue-types';
|
||||
import type { VueNode } from '../_util/type';
|
||||
import { tuple } from '../_util/type';
|
||||
import type { PropType, ExtractPropTypes } from 'vue';
|
||||
import { functionType, stringType, anyType, objectType } from '../_util/type';
|
||||
import type { ExtractPropTypes } from 'vue';
|
||||
|
||||
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 const progressStatuses = ['normal', 'exception', 'active', 'success'] as const;
|
||||
export type ProgressStatusesType = (typeof progressStatuses)[number];
|
||||
const ProgressType = ['line', 'circle', 'dashboard'] as const;
|
||||
export type ProgressType = (typeof ProgressType)[number];
|
||||
const ProgressSize = ['default', 'small'] as const;
|
||||
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 interface SuccessProps {
|
||||
percent?: number;
|
||||
/** @deprecated Use `percent` instead */
|
||||
progress?: number;
|
||||
strokeColor?: string;
|
||||
}
|
||||
|
||||
export const progressProps = () => ({
|
||||
prefixCls: String,
|
||||
type: PropTypes.oneOf(ProgressType),
|
||||
type: stringType<ProgressType>(),
|
||||
percent: Number,
|
||||
format: { type: Function as PropType<(percent?: number, successPercent?: number) => VueNode> },
|
||||
status: PropTypes.oneOf(progressStatuses),
|
||||
format: functionType<(percent?: number, successPercent?: number) => VueNode>(),
|
||||
status: stringType<ProgressStatusesType>(),
|
||||
showInfo: { type: Boolean, default: undefined },
|
||||
strokeWidth: Number,
|
||||
strokeLinecap: String as PropType<'butt' | 'square' | 'round'>,
|
||||
strokeColor: {
|
||||
type: [String, Object] as PropType<string | ProgressGradient>,
|
||||
default: undefined as string | ProgressGradient,
|
||||
},
|
||||
strokeLinecap: stringType<'butt' | 'square' | 'round'>(),
|
||||
strokeColor: anyType<string | ProgressGradient>(),
|
||||
trailColor: String,
|
||||
width: Number,
|
||||
success: {
|
||||
type: Object as PropType<SuccessProps>,
|
||||
default: (): SuccessProps => ({}),
|
||||
},
|
||||
success: objectType<SuccessProps>(),
|
||||
gapDegree: Number,
|
||||
gapPosition: String as PropType<'top' | 'bottom' | 'left' | 'right'>,
|
||||
size: PropTypes.oneOf(ProgressSize),
|
||||
gapPosition: stringType<'top' | 'bottom' | 'left' | 'right'>(),
|
||||
size: stringType<ProgressSize>(),
|
||||
steps: Number,
|
||||
/** @deprecated Use `success` instead */
|
||||
successPercent: Number,
|
||||
|
@ -1,4 +1,7 @@
|
||||
import { presetPrimaryColors } from '@ant-design/colors';
|
||||
import devWarning from '../vc-util/devWarning';
|
||||
import type { CircleProps } from './Circle';
|
||||
import type { ProgressProps } from './props';
|
||||
|
||||
export function validProgress(progress: number | undefined) {
|
||||
if (!progress || progress < 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 function getPercentage({ percent, success, successPercent }: ProgressProps) {
|
||||
const realSuccessPercent = validProgress(getSuccessPercent({ success, successPercent }));
|
||||
return [realSuccessPercent, validProgress(validProgress(percent) - realSuccessPercent)];
|
||||
}
|
||||
|
||||
export function getStrokeColor({
|
||||
success = {},
|
||||
strokeColor,
|
||||
}: Partial<CircleProps>): (string | Record<string, string>)[] {
|
||||
const { strokeColor: successColor } = success;
|
||||
return [successColor || presetPrimaryColors.green, strokeColor || null!];
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user