feat: progress add inside and bottom text position (#48157)

* feat: progress add inside and bottom text position

* feat: change progress percent position api

* fix: change to follow coding standards

* docs: reset i18n zh file

* fix: change to follow coding standards

* fix: change to follow coding standards

* docs: reset i18n file

* fix: change to follow coding standards

* docs: reset i18n file

* feat: progress inner text get brighten color

* feat: update progress snapshots

* fix: progress bottom layout center

* feat: update steps snapshots

* feat: update progress snapshots

* feat: update config provider snapshots

* feat: progress inner text add negate color

* feat: update progress snapshots

* feat: progress inner text add light bg color

* feat: progress inner text add light bg color

* feat: change progress percentPosition api

* feat: change progress component test

* feat: update progress line component snapshot

* feat: progress component outer start layout text adapt

* feat: progress line change to flex layout

* feat: update progress snapshots

* feat: update progress line style

* feat: update progress line style

* fix: progress line reset height use inline block

* fix: change progress is line type

* fix: change progress is line type

* fix: delete progress outer styles

* fix: change progress line type layout

* fix: progress add outer style

* feat: update progress snapshots

* fix: change progress text bright color

* fix: optimized code volume

* fix: progress delete after style on inner layout

* fix: update progress test file

---------

Co-authored-by: lijianan <574980606@qq.com>
Co-authored-by: afc163 <afc163@gmail.com>
This commit is contained in:
LonelySnowman 2024-05-10 10:22:32 +08:00 committed by GitHub
parent a343fcd035
commit 5098e6e209
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 1441 additions and 689 deletions

View File

@ -21792,196 +21792,196 @@ exports[`ConfigProvider components Popover prefixCls 1`] = `
exports[`ConfigProvider components Progress configProvider 1`] = `
<div
aria-valuenow="0"
class="config-progress config-progress-status-normal config-progress-line config-progress-show-info config-progress-default"
class="config-progress config-progress-status-normal config-progress-line config-progress-line-align-end config-progress-line-position-outer config-progress-show-info config-progress-default"
role="progressbar"
>
<div
class="config-progress-outer"
style="width: 100%; height: 8px;"
style="width: 100%;"
>
<div
class="config-progress-inner"
>
<div
class="config-progress-bg"
class="config-progress-bg config-progress-bg-outer"
style="width: 0%; height: 8px; --progress-percent: 0;"
/>
</div>
<span
class="config-progress-text config-progress-text-end config-progress-text-outer"
title="0%"
>
0%
</span>
</div>
<span
class="config-progress-text"
title="0%"
>
0%
</span>
</div>
`;
exports[`ConfigProvider components Progress configProvider componentDisabled 1`] = `
<div
aria-valuenow="0"
class="config-progress config-progress-status-normal config-progress-line config-progress-show-info config-progress-default"
class="config-progress config-progress-status-normal config-progress-line config-progress-line-align-end config-progress-line-position-outer config-progress-show-info config-progress-default"
role="progressbar"
>
<div
class="config-progress-outer"
style="width: 100%; height: 8px;"
style="width: 100%;"
>
<div
class="config-progress-inner"
>
<div
class="config-progress-bg"
class="config-progress-bg config-progress-bg-outer"
style="width: 0%; height: 8px; --progress-percent: 0;"
/>
</div>
<span
class="config-progress-text config-progress-text-end config-progress-text-outer"
title="0%"
>
0%
</span>
</div>
<span
class="config-progress-text"
title="0%"
>
0%
</span>
</div>
`;
exports[`ConfigProvider components Progress configProvider componentSize large 1`] = `
<div
aria-valuenow="0"
class="config-progress config-progress-status-normal config-progress-line config-progress-show-info config-progress-default"
class="config-progress config-progress-status-normal config-progress-line config-progress-line-align-end config-progress-line-position-outer config-progress-show-info config-progress-default"
role="progressbar"
>
<div
class="config-progress-outer"
style="width: 100%; height: 8px;"
style="width: 100%;"
>
<div
class="config-progress-inner"
>
<div
class="config-progress-bg"
class="config-progress-bg config-progress-bg-outer"
style="width: 0%; height: 8px; --progress-percent: 0;"
/>
</div>
<span
class="config-progress-text config-progress-text-end config-progress-text-outer"
title="0%"
>
0%
</span>
</div>
<span
class="config-progress-text"
title="0%"
>
0%
</span>
</div>
`;
exports[`ConfigProvider components Progress configProvider componentSize middle 1`] = `
<div
aria-valuenow="0"
class="config-progress config-progress-status-normal config-progress-line config-progress-show-info config-progress-default"
class="config-progress config-progress-status-normal config-progress-line config-progress-line-align-end config-progress-line-position-outer config-progress-show-info config-progress-default"
role="progressbar"
>
<div
class="config-progress-outer"
style="width: 100%; height: 8px;"
style="width: 100%;"
>
<div
class="config-progress-inner"
>
<div
class="config-progress-bg"
class="config-progress-bg config-progress-bg-outer"
style="width: 0%; height: 8px; --progress-percent: 0;"
/>
</div>
<span
class="config-progress-text config-progress-text-end config-progress-text-outer"
title="0%"
>
0%
</span>
</div>
<span
class="config-progress-text"
title="0%"
>
0%
</span>
</div>
`;
exports[`ConfigProvider components Progress configProvider componentSize small 1`] = `
<div
aria-valuenow="0"
class="config-progress config-progress-status-normal config-progress-line config-progress-show-info config-progress-default"
class="config-progress config-progress-status-normal config-progress-line config-progress-line-align-end config-progress-line-position-outer config-progress-show-info config-progress-default"
role="progressbar"
>
<div
class="config-progress-outer"
style="width: 100%; height: 8px;"
style="width: 100%;"
>
<div
class="config-progress-inner"
>
<div
class="config-progress-bg"
class="config-progress-bg config-progress-bg-outer"
style="width: 0%; height: 8px; --progress-percent: 0;"
/>
</div>
<span
class="config-progress-text config-progress-text-end config-progress-text-outer"
title="0%"
>
0%
</span>
</div>
<span
class="config-progress-text"
title="0%"
>
0%
</span>
</div>
`;
exports[`ConfigProvider components Progress normal 1`] = `
<div
aria-valuenow="0"
class="ant-progress ant-progress-status-normal ant-progress-line ant-progress-show-info ant-progress-default"
class="ant-progress ant-progress-status-normal ant-progress-line ant-progress-line-align-end ant-progress-line-position-outer ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
style="width: 100%; height: 8px;"
style="width: 100%;"
>
<div
class="ant-progress-inner"
>
<div
class="ant-progress-bg"
class="ant-progress-bg ant-progress-bg-outer"
style="width: 0%; height: 8px; --progress-percent: 0;"
/>
</div>
<span
class="ant-progress-text ant-progress-text-end ant-progress-text-outer"
title="0%"
>
0%
</span>
</div>
<span
class="ant-progress-text"
title="0%"
>
0%
</span>
</div>
`;
exports[`ConfigProvider components Progress prefixCls 1`] = `
<div
aria-valuenow="0"
class="prefix-Progress prefix-Progress-status-normal prefix-Progress-line prefix-Progress-show-info prefix-Progress-default"
class="prefix-Progress prefix-Progress-status-normal prefix-Progress-line prefix-Progress-line-align-end prefix-Progress-line-position-outer prefix-Progress-show-info prefix-Progress-default"
role="progressbar"
>
<div
class="prefix-Progress-outer"
style="width: 100%; height: 8px;"
style="width: 100%;"
>
<div
class="prefix-Progress-inner"
>
<div
class="prefix-Progress-bg"
class="prefix-Progress-bg prefix-Progress-bg-outer"
style="width: 0%; height: 8px; --progress-percent: 0;"
/>
</div>
<span
class="prefix-Progress-text prefix-Progress-text-end prefix-Progress-text-outer"
title="0%"
>
0%
</span>
</div>
<span
class="prefix-Progress-text"
title="0%"
>
0%
</span>
</div>
`;

View File

@ -1,17 +1,22 @@
import * as React from 'react';
import { presetPrimaryColors } from '@ant-design/colors';
import classNames from 'classnames';
import { devUseWarning } from '../_util/warning';
import type { DirectionType } from '../config-provider';
import type { ProgressGradient, ProgressProps, StringGradients } from './progress';
import type {
ProgressGradient,
ProgressProps,
StringGradients,
PercentPositionType,
} from './progress';
import { LineStrokeColorVar, Percent } from './style';
import { getSize, getSuccessPercent, validProgress } from './utils';
interface LineProps extends ProgressProps {
prefixCls: string;
direction?: DirectionType;
children: React.ReactNode;
strokeColor?: string | ProgressGradient;
percentPosition: PercentPositionType;
}
/**
@ -82,9 +87,12 @@ const Line: React.FC<LineProps> = (props) => {
strokeLinecap = 'round',
children,
trailColor = null,
percentPosition,
success,
} = props;
const { align: infoAlign, type: infoPosition } = percentPosition;
const backgroundProps =
strokeColor && typeof strokeColor !== 'string'
? handleGradient(strokeColor, directionConfig)
@ -126,21 +134,36 @@ const Line: React.FC<LineProps> = (props) => {
const outerStyle: React.CSSProperties = {
width: width < 0 ? '100%' : width,
height,
};
return (
<>
<div className={`${prefixCls}-outer`} style={outerStyle}>
<div className={`${prefixCls}-inner`} style={trailStyle}>
<div className={`${prefixCls}-bg`} style={percentStyle} />
{successPercent !== undefined ? (
<div className={`${prefixCls}-success-bg`} style={successPercentStyle} />
) : null}
</div>
const lineInner = (
<div className={`${prefixCls}-inner`} style={trailStyle}>
<div
className={classNames(`${prefixCls}-bg`, `${prefixCls}-bg-${infoPosition}`)}
style={percentStyle}
>
{infoPosition === 'inner' && children}
</div>
{successPercent !== undefined && (
<div className={`${prefixCls}-success-bg`} style={successPercentStyle} />
)}
</div>
);
const isOuterStart = infoPosition === 'outer' && infoAlign === 'start';
const isOuterEnd = infoPosition === 'outer' && infoAlign === 'end';
return infoPosition === 'outer' && infoAlign === 'center' ? (
<div className={`${prefixCls}-layout-bottom`}>
{lineInner}
{children}
</>
</div>
) : (
<div className={`${prefixCls}-outer`} style={outerStyle}>
{isOuterStart && children}
{lineInner}
{isOuterEnd && children}
</div>
);
};

File diff suppressed because it is too large Load Diff

View File

@ -246,18 +246,18 @@ exports[`Progress render dashboard zero gapDegree 1`] = `
exports[`Progress render format 1`] = `
<div
aria-valuenow="10"
class="ant-progress ant-progress-status-normal ant-progress-line ant-progress-show-info ant-progress-default"
class="ant-progress ant-progress-status-normal ant-progress-line ant-progress-line-align-end ant-progress-line-position-outer ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
style="width: 100%; height: 8px;"
style="width: 100%;"
>
<div
class="ant-progress-inner"
>
<div
class="ant-progress-bg"
class="ant-progress-bg ant-progress-bg-outer"
style="width: 50%; height: 8px; --progress-percent: 0.5;"
/>
<div
@ -265,59 +265,88 @@ exports[`Progress render format 1`] = `
style="width: 10%; height: 8px;"
/>
</div>
<span
class="ant-progress-text ant-progress-text-end ant-progress-text-outer"
title="50 10"
>
50 10
</span>
</div>
<span
class="ant-progress-text"
title="50 10"
</div>
`;
exports[`Progress render inner info position 1`] = `
<div
aria-valuenow="100"
class="ant-progress ant-progress-status-success ant-progress-line ant-progress-line-align-center ant-progress-line-position-inner ant-progress-show-info"
role="progressbar"
>
<div
class="ant-progress-outer"
style="width: 400px;"
>
50 10
</span>
<div
class="ant-progress-inner"
>
<div
class="ant-progress-bg ant-progress-bg-inner"
style="width: 100%; height: 20px; --progress-percent: 1;"
>
<span
class="ant-progress-text ant-progress-text-center ant-progress-text-inner"
title="100%"
>
100%
</span>
</div>
</div>
</div>
</div>
`;
exports[`Progress render negative progress 1`] = `
<div
aria-valuenow="-20"
class="ant-progress ant-progress-status-normal ant-progress-line ant-progress-show-info ant-progress-default"
class="ant-progress ant-progress-status-normal ant-progress-line ant-progress-line-align-end ant-progress-line-position-outer ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
style="width: 100%; height: 8px;"
style="width: 100%;"
>
<div
class="ant-progress-inner"
>
<div
class="ant-progress-bg"
class="ant-progress-bg ant-progress-bg-outer"
style="width: 0%; height: 8px; --progress-percent: 0;"
/>
</div>
<span
class="ant-progress-text ant-progress-text-end ant-progress-text-outer"
title="0%"
>
0%
</span>
</div>
<span
class="ant-progress-text"
title="0%"
>
0%
</span>
</div>
`;
exports[`Progress render negative successPercent 1`] = `
<div
aria-valuenow="-20"
class="ant-progress ant-progress-status-normal ant-progress-line ant-progress-show-info ant-progress-default"
class="ant-progress ant-progress-status-normal ant-progress-line ant-progress-line-align-end ant-progress-line-position-outer ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
style="width: 100%; height: 8px;"
style="width: 100%;"
>
<div
class="ant-progress-inner"
>
<div
class="ant-progress-bg"
class="ant-progress-bg ant-progress-bg-outer"
style="width: 50%; height: 8px; --progress-percent: 0.5;"
/>
<div
@ -325,131 +354,131 @@ exports[`Progress render negative successPercent 1`] = `
style="width: 0%; height: 8px;"
/>
</div>
<span
class="ant-progress-text ant-progress-text-end ant-progress-text-outer"
title="50%"
>
50%
</span>
</div>
<span
class="ant-progress-text"
title="50%"
>
50%
</span>
</div>
`;
exports[`Progress render normal progress 1`] = `
<div
aria-valuenow="0"
class="ant-progress ant-progress-status-normal ant-progress-line ant-progress-show-info ant-progress-default"
class="ant-progress ant-progress-status-normal ant-progress-line ant-progress-line-align-end ant-progress-line-position-outer ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
style="width: 100%; height: 8px;"
style="width: 100%;"
>
<div
class="ant-progress-inner"
>
<div
class="ant-progress-bg"
class="ant-progress-bg ant-progress-bg-outer"
style="width: 0%; height: 8px; --progress-percent: 0;"
/>
</div>
<span
class="ant-progress-text ant-progress-text-end ant-progress-text-outer"
title="0%"
>
0%
</span>
</div>
<span
class="ant-progress-text"
title="0%"
>
0%
</span>
</div>
`;
exports[`Progress render out-of-range progress 1`] = `
<div
aria-valuenow="120"
class="ant-progress ant-progress-status-success ant-progress-line ant-progress-show-info ant-progress-default"
class="ant-progress ant-progress-status-success ant-progress-line ant-progress-line-align-end ant-progress-line-position-outer ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
style="width: 100%; height: 8px;"
style="width: 100%;"
>
<div
class="ant-progress-inner"
>
<div
class="ant-progress-bg"
class="ant-progress-bg ant-progress-bg-outer"
style="width: 100%; height: 8px; --progress-percent: 1;"
/>
</div>
</div>
<span
class="ant-progress-text"
>
<span
aria-label="check-circle"
class="anticon anticon-check-circle"
role="img"
class="ant-progress-text ant-progress-text-end ant-progress-text-outer"
>
<svg
aria-hidden="true"
data-icon="check-circle"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
<span
aria-label="check-circle"
class="anticon anticon-check-circle"
role="img"
>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm193.5 301.7l-210.6 292a31.8 31.8 0 01-51.7 0L318.5 484.9c-3.8-5.3 0-12.7 6.5-12.7h46.9c10.2 0 19.9 4.9 25.9 13.3l71.2 98.8 157.2-218c6-8.3 15.6-13.3 25.9-13.3H699c6.5 0 10.3 7.4 6.5 12.7z"
/>
</svg>
<svg
aria-hidden="true"
data-icon="check-circle"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm193.5 301.7l-210.6 292a31.8 31.8 0 01-51.7 0L318.5 484.9c-3.8-5.3 0-12.7 6.5-12.7h46.9c10.2 0 19.9 4.9 25.9 13.3l71.2 98.8 157.2-218c6-8.3 15.6-13.3 25.9-13.3H699c6.5 0 10.3 7.4 6.5 12.7z"
/>
</svg>
</span>
</span>
</span>
</div>
</div>
`;
exports[`Progress render out-of-range progress with info 1`] = `
<div
aria-valuenow="120"
class="ant-progress ant-progress-status-success ant-progress-line ant-progress-show-info ant-progress-default"
class="ant-progress ant-progress-status-success ant-progress-line ant-progress-line-align-end ant-progress-line-position-outer ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
style="width: 100%; height: 8px;"
style="width: 100%;"
>
<div
class="ant-progress-inner"
>
<div
class="ant-progress-bg"
class="ant-progress-bg ant-progress-bg-outer"
style="width: 100%; height: 8px; --progress-percent: 1;"
/>
</div>
</div>
<span
class="ant-progress-text"
>
<span
aria-label="check-circle"
class="anticon anticon-check-circle"
role="img"
class="ant-progress-text ant-progress-text-end ant-progress-text-outer"
>
<svg
aria-hidden="true"
data-icon="check-circle"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
<span
aria-label="check-circle"
class="anticon anticon-check-circle"
role="img"
>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm193.5 301.7l-210.6 292a31.8 31.8 0 01-51.7 0L318.5 484.9c-3.8-5.3 0-12.7 6.5-12.7h46.9c10.2 0 19.9 4.9 25.9 13.3l71.2 98.8 157.2-218c6-8.3 15.6-13.3 25.9-13.3H699c6.5 0 10.3 7.4 6.5 12.7z"
/>
</svg>
<svg
aria-hidden="true"
data-icon="check-circle"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm193.5 301.7l-210.6 292a31.8 31.8 0 01-51.7 0L318.5 484.9c-3.8-5.3 0-12.7 6.5-12.7h46.9c10.2 0 19.9 4.9 25.9 13.3l71.2 98.8 157.2-218c6-8.3 15.6-13.3 25.9-13.3H699c6.5 0 10.3 7.4 6.5 12.7z"
/>
</svg>
</span>
</span>
</span>
</div>
</div>
`;
@ -511,56 +540,56 @@ exports[`Progress render strokeColor 1`] = `
exports[`Progress render strokeColor 2`] = `
<div
aria-valuenow="50"
class="ant-progress ant-progress-status-normal ant-progress-line ant-progress-show-info ant-progress-default"
class="ant-progress ant-progress-status-normal ant-progress-line ant-progress-line-align-end ant-progress-line-position-outer ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
style="width: 100%; height: 8px;"
style="width: 100%;"
>
<div
class="ant-progress-inner"
>
<div
class="ant-progress-bg"
class="ant-progress-bg ant-progress-bg-outer"
style="width: 50%; height: 8px; --progress-line-stroke-color: linear-gradient(to right, #108ee9, #87d068); --progress-percent: 0.5;"
/>
</div>
<span
class="ant-progress-text ant-progress-text-end ant-progress-text-outer"
title="50%"
>
50%
</span>
</div>
<span
class="ant-progress-text"
title="50%"
>
50%
</span>
</div>
`;
exports[`Progress render strokeColor 3`] = `
<div
aria-valuenow="50"
class="ant-progress ant-progress-status-normal ant-progress-line ant-progress-show-info ant-progress-default"
class="ant-progress ant-progress-status-normal ant-progress-line ant-progress-line-align-end ant-progress-line-position-outer ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
style="width: 100%; height: 8px;"
style="width: 100%;"
>
<div
class="ant-progress-inner"
>
<div
class="ant-progress-bg"
class="ant-progress-bg ant-progress-bg-outer"
style="width: 50%; height: 8px; --progress-line-stroke-color: linear-gradient(to right, #108ee9 0%, #87d068 100%); --progress-percent: 0.5;"
/>
</div>
<span
class="ant-progress-text ant-progress-text-end ant-progress-text-outer"
title="50%"
>
50%
</span>
</div>
<span
class="ant-progress-text"
title="50%"
>
50%
</span>
</div>
`;
@ -624,18 +653,18 @@ exports[`Progress render strokeWidth of progress 1`] = `
exports[`Progress render successColor progress 1`] = `
<div
aria-valuenow="30"
class="ant-progress ant-progress-status-normal ant-progress-line ant-progress-show-info ant-progress-default"
class="ant-progress ant-progress-status-normal ant-progress-line ant-progress-line-align-end ant-progress-line-position-outer ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
style="width: 100%; height: 8px;"
style="width: 100%;"
>
<div
class="ant-progress-inner"
>
<div
class="ant-progress-bg"
class="ant-progress-bg ant-progress-bg-outer"
style="width: 60%; height: 8px; --progress-percent: 0.6;"
/>
<div
@ -643,13 +672,13 @@ exports[`Progress render successColor progress 1`] = `
style="width: 30%; height: 8px; background-color: rgb(255, 255, 255);"
/>
</div>
<span
class="ant-progress-text ant-progress-text-end ant-progress-text-outer"
title="60%"
>
60%
</span>
</div>
<span
class="ant-progress-text"
title="60%"
>
60%
</span>
</div>
`;
@ -766,57 +795,57 @@ exports[`Progress render successColor progress type="dashboard" 1`] = `
exports[`Progress render trailColor progress 1`] = `
<div
aria-valuenow="0"
class="ant-progress ant-progress-status-normal ant-progress-line ant-progress-show-info ant-progress-default"
class="ant-progress ant-progress-status-normal ant-progress-line ant-progress-line-align-end ant-progress-line-position-outer ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
style="width: 100%; height: 8px;"
style="width: 100%;"
>
<div
class="ant-progress-inner"
style="background-color: rgb(255, 255, 255);"
>
<div
class="ant-progress-bg"
class="ant-progress-bg ant-progress-bg-outer"
style="width: 0%; height: 8px; --progress-percent: 0;"
/>
</div>
<span
class="ant-progress-text ant-progress-text-end ant-progress-text-outer"
title="0%"
>
0%
</span>
</div>
<span
class="ant-progress-text"
title="0%"
>
0%
</span>
</div>
`;
exports[`Progress rtl render component should be rendered correctly in RTL direction 1`] = `
<div
aria-valuenow="0"
class="ant-progress ant-progress-status-normal ant-progress-line ant-progress-show-info ant-progress-default ant-progress-rtl"
class="ant-progress ant-progress-status-normal ant-progress-line ant-progress-line-align-end ant-progress-line-position-outer ant-progress-show-info ant-progress-default ant-progress-rtl"
role="progressbar"
>
<div
class="ant-progress-outer"
style="width: 100%; height: 8px;"
style="width: 100%;"
>
<div
class="ant-progress-inner"
>
<div
class="ant-progress-bg"
class="ant-progress-bg ant-progress-bg-outer"
style="width: 0%; height: 8px; --progress-percent: 0;"
/>
</div>
<span
class="ant-progress-text ant-progress-text-end ant-progress-text-outer"
title="0%"
>
0%
</span>
</div>
<span
class="ant-progress-text"
title="0%"
>
0%
</span>
</div>
`;

View File

@ -340,9 +340,6 @@ describe('Progress', () => {
);
const { container, rerender } = render(<App size={30} />);
expect(container.querySelector('.ant-progress-line .ant-progress-outer')).toHaveStyle({
width: '30px',
});
expect(container.querySelector('.ant-progress-steps .ant-progress-steps-item')).toHaveStyle({
width: '30px',
height: '30px',
@ -360,6 +357,8 @@ describe('Progress', () => {
expect(container.querySelector('.ant-progress-line .ant-progress-outer')).toHaveStyle({
width: '60px',
});
expect(container.querySelector('.ant-progress-line .ant-progress-bg')).toHaveStyle({
height: '20px',
});
expect(container.querySelector('.ant-progress-steps .ant-progress-steps-item')).toHaveStyle({
@ -379,6 +378,8 @@ describe('Progress', () => {
expect(container.querySelector('.ant-progress-line .ant-progress-outer')).toHaveStyle({
width: '60px',
});
expect(container.querySelector('.ant-progress-line .ant-progress-bg')).toHaveStyle({
height: '20px',
});
expect(container.querySelector('.ant-progress-steps .ant-progress-steps-item')).toHaveStyle({
@ -433,4 +434,40 @@ describe('Progress', () => {
const { container } = render(<Progress percent={70} steps={5} />);
expect(container.firstChild).toMatchSnapshot();
});
it('should show inner info position', () => {
const { container: wrapper, rerender } = render(
<Progress
percent={0}
percentPosition={{ align: 'center', type: 'inner' }}
size={[200, 20]}
/>,
);
expect(
wrapper.querySelectorAll('.ant-progress-line-align-center.ant-progress-line-position-inner'),
).toHaveLength(1);
rerender(
<Progress
percent={100}
percentPosition={{ align: 'center', type: 'inner' }}
size={[400, 20]}
/>,
);
expect(wrapper.querySelectorAll('.ant-progress-text-inner')).toHaveLength(1);
rerender(<Progress percent={100} percentPosition={{ align: 'center', type: 'outer' }} />);
expect(wrapper.querySelectorAll('.ant-progress-layout-bottom')).toHaveLength(1);
});
it('render inner info position', () => {
const { container } = render(
<Progress
percent={100}
percentPosition={{ align: 'center', type: 'inner' }}
size={[400, 20]}
/>,
);
expect(container.firstChild).toMatchSnapshot();
});
});

View File

@ -0,0 +1,7 @@
## zh-CN
改变进度数值位置,可使用 `percentPosition` 调整,使进度条数值在进度条内部、外部或底部。
## en-US
Change the position of the progress value, you can use `percentPosition` to adjust it so that the progress bar value is inside, outside or at the bottom of the progress bar.

View File

@ -0,0 +1,33 @@
import React from 'react';
import { Flex, Progress } from 'antd';
const App: React.FC = () => (
<Flex gap="small" vertical>
<Progress
percent={0}
percentPosition={{ align: 'center', type: 'inner' }}
size={[200, 20]}
strokeColor="#E6F4FF"
/>
<Progress percent={10} percentPosition={{ align: 'center', type: 'inner' }} size={[300, 20]} />
<Progress
percent={50}
percentPosition={{ align: 'start', type: 'inner' }}
size={[300, 20]}
strokeColor="#B7EB8F"
/>
<Progress
percent={60}
percentPosition={{ align: 'end', type: 'inner' }}
size={[300, 20]}
strokeColor="#001342"
/>
<Progress percent={100} percentPosition={{ align: 'center', type: 'inner' }} size={[400, 20]} />
<Progress percent={60} percentPosition={{ align: 'start', type: 'outer' }} />
<Progress percent={100} percentPosition={{ align: 'start', type: 'outer' }} />
<Progress percent={60} percentPosition={{ align: 'center', type: 'outer' }} size="small" />
<Progress percent={100} percentPosition={{ align: 'center', type: 'outer' }} />
</Flex>
);
export default App;

View File

@ -33,6 +33,7 @@ If it will take a long time to complete an operation, you can use `Progress` to
<code src="./demo/steps.tsx">Progress bar with steps</code>
<code src="./demo/circle-steps.tsx" version="5.16.0">Circular progress bar whit steps</code>
<code src="./demo/size.tsx">Progress size</code>
<code src="./demo/info-position.tsx" version="5.18.0">Change progress value position</code>
## API
@ -59,6 +60,7 @@ Properties that shared by all types.
| --- | --- | --- | --- | --- |
| steps | The total step count | number | - | - |
| strokeColor | The color of progress bar, render `linear-gradient` when passing an object, could accept `string[]` when has `steps`. | string \| string[] \| { from: string; to: string; direction: string } | - | 4.21.0: `string[]` |
| percentPosition | Progress value position, passed in object, `align` indicates the horizontal position of the value, `type` indicates whether the value is inside or outside the progress bar | { align: string; type: string } | { align: \"end\", type: \"outer\" } | 5.18.0 |
### `type="circle"`

View File

@ -34,6 +34,7 @@ demo:
<code src="./demo/steps.tsx">步骤进度条</code>
<code src="./demo/circle-steps.tsx" version="5.16.0">步骤进度圈</code>
<code src="./demo/size.tsx">尺寸</code>
<code src="./demo/info-position.tsx" version="5.18.0">改变进度数值位置</code>
## API
@ -60,6 +61,7 @@ demo:
| --- | --- | --- | --- | --- |
| steps | 进度条总共步数 | number | - | - |
| strokeColor | 进度条的色彩,传入 object 时为渐变。当有 `steps` 时支持传入一个数组。 | string \| string[] \| { from: string; to: string; direction: string } | - | 4.21.0: `string[]` |
| percentPosition | 进度数值位置,传入对象,`align` 表示数值的水平位置,`type` 表示数值在进度条内部还是外部 | { align: string; type: string } | { align: \"end\", type: \"outer\" } | 5.18.0 |
### `type="circle"`

View File

@ -14,15 +14,19 @@ import Line from './Line';
import Steps from './Steps';
import useStyle from './style';
import { getSize, getSuccessPercent, validProgress } from './utils';
import { TinyColor } from '@ctrl/tinycolor';
export const ProgressTypes = ['line', 'circle', 'dashboard'] as const;
export type ProgressType = (typeof ProgressTypes)[number];
const ProgressStatuses = ['normal', 'exception', 'active', 'success'] as const;
export type ProgressSize = 'default' | 'small';
export type StringGradients = Record<string, string>;
type FromToGradients = { from: string; to: string };
export type ProgressGradient = { direction?: string } & (StringGradients | FromToGradients);
export interface PercentPositionType {
align?: 'start' | 'center' | 'end';
type?: 'inner' | 'outer';
}
export interface SuccessProps {
percent?: number;
@ -56,6 +60,7 @@ export interface ProgressProps extends ProgressAriaProps {
steps?: number | { count: number; gap: number };
/** @deprecated Use `success` instead */
successPercent?: number;
percentPosition?: PercentPositionType;
children?: React.ReactNode;
}
@ -73,9 +78,25 @@ const Progress = React.forwardRef<HTMLDivElement, ProgressProps>((props, ref) =>
status,
format,
style,
percentPosition = {},
...restProps
} = props;
const { align: infoAlign = 'end', type: infoPosition = 'outer' } = percentPosition;
const strokeColorNotArray = Array.isArray(strokeColor) ? strokeColor[0] : strokeColor;
const strokeColorNotGradient =
typeof strokeColor === 'string' || Array.isArray(strokeColor) ? strokeColor : undefined;
const strokeColorIsBright = React.useMemo(() => {
if (strokeColorNotArray) {
const color =
typeof strokeColorNotArray === 'string'
? strokeColorNotArray
: Object.values(strokeColorNotArray)[0];
return new TinyColor(color).isLight();
}
return false;
}, [strokeColor]);
const percentNumber = React.useMemo<number>(() => {
const successPercent = getSuccessPercent(props);
return parseInt(
@ -99,6 +120,8 @@ const Progress = React.forwardRef<HTMLDivElement, ProgressProps>((props, ref) =>
const prefixCls = getPrefixCls('progress', customizePrefixCls);
const [wrapCSSVar, hashId, cssVarCls] = useStyle(prefixCls);
const isLineType = type === 'line';
const isPureLineType = isLineType && !steps;
const progressInfo = React.useMemo<React.ReactNode>(() => {
if (!showInfo) {
return null;
@ -106,8 +129,12 @@ const Progress = React.forwardRef<HTMLDivElement, ProgressProps>((props, ref) =>
const successPercent = getSuccessPercent(props);
let text: React.ReactNode;
const textFormatter = format || ((number) => `${number}%`);
const isLineType = type === 'line';
if (format || (progressStatus !== 'exception' && progressStatus !== 'success')) {
const isBrightInnerColor = isLineType && strokeColorIsBright && infoPosition === 'inner';
if (
infoPosition === 'inner' ||
format ||
(progressStatus !== 'exception' && progressStatus !== 'success')
) {
text = textFormatter(validProgress(percent), validProgress(successPercent));
} else if (progressStatus === 'exception') {
text = isLineType ? <CloseCircleFilled /> : <CloseOutlined />;
@ -116,7 +143,14 @@ const Progress = React.forwardRef<HTMLDivElement, ProgressProps>((props, ref) =>
}
return (
<span className={`${prefixCls}-text`} title={typeof text === 'string' ? text : undefined}>
<span
className={classNames(`${prefixCls}-text`, {
[`${prefixCls}-text-bright`]: isBrightInnerColor,
[`${prefixCls}-text-${infoAlign}`]: isPureLineType,
[`${prefixCls}-text-${infoPosition}`]: isPureLineType,
})}
title={typeof text === 'string' ? text : undefined}
>
{text}
</span>
);
@ -149,9 +183,6 @@ const Progress = React.forwardRef<HTMLDivElement, ProgressProps>((props, ref) =>
}
}
const strokeColorNotArray = Array.isArray(strokeColor) ? strokeColor[0] : strokeColor;
const strokeColorNotGradient =
typeof strokeColor === 'string' || Array.isArray(strokeColor) ? strokeColor : undefined;
let progress: React.ReactNode;
// Render progress shape
if (type === 'line') {
@ -170,6 +201,10 @@ const Progress = React.forwardRef<HTMLDivElement, ProgressProps>((props, ref) =>
strokeColor={strokeColorNotArray}
prefixCls={prefixCls}
direction={direction}
percentPosition={{
align: infoAlign,
type: infoPosition,
}}
>
{progressInfo}
</Line>
@ -193,7 +228,9 @@ const Progress = React.forwardRef<HTMLDivElement, ProgressProps>((props, ref) =>
{
[`${prefixCls}-${(type === 'dashboard' && 'circle') || type}`]: type !== 'line',
[`${prefixCls}-inline-circle`]: type === 'circle' && getSize(size, 'circle')[0] <= 20,
[`${prefixCls}-line`]: !steps && type === 'line',
[`${prefixCls}-line`]: isPureLineType,
[`${prefixCls}-line-align-${infoAlign}`]: isPureLineType,
[`${prefixCls}-line-position-${infoPosition}`]: isPureLineType,
[`${prefixCls}-steps`]: steps,
[`${prefixCls}-show-info`]: showInfo,
[`${prefixCls}-${size}`]: typeof size === 'string',

View File

@ -1,5 +1,5 @@
import type { CSSObject } from '@ant-design/cssinjs';
import { Keyframes, unit } from '@ant-design/cssinjs';
import { Keyframes } from '@ant-design/cssinjs';
import { resetComponent } from '../../style';
import type { FullToken, GenerateStyle, GetDefaultToken } from '../../theme/internal';
@ -85,21 +85,16 @@ const genBaseStyle: GenerateStyle<ProgressToken> = (token) => {
},
[`${progressCls}-outer`]: {
display: 'inline-block',
display: 'inline-flex',
alignItems: 'center',
width: '100%',
},
[`&${progressCls}-show-info`]: {
[`${progressCls}-outer`]: {
marginInlineEnd: `calc(-2em - ${unit(token.marginXS)})`,
paddingInlineEnd: `calc(2em + ${unit(token.paddingXS)})`,
},
},
[`${progressCls}-inner`]: {
position: 'relative',
display: 'inline-block',
width: '100%',
flex: 1,
overflow: 'hidden',
verticalAlign: 'middle',
backgroundColor: token.remainingColor,
@ -119,9 +114,20 @@ const genBaseStyle: GenerateStyle<ProgressToken> = (token) => {
transition: `all ${token.motionDurationSlow} ${token.motionEaseInOutCirc}`,
},
[`${progressCls}-layout-bottom`]: {
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
[`${progressCls}-text`]: {
width: 'max-content',
marginInlineStart: 0,
marginTop: token.marginXXS,
},
},
[`${progressCls}-bg`]: {
overflow: 'hidden',
'&::after': {
content: '""',
background: {
@ -132,6 +138,18 @@ const genBaseStyle: GenerateStyle<ProgressToken> = (token) => {
width: `calc(1 / var(${Percent}) * 100%)`,
display: 'block',
},
[`&${progressCls}-bg-inner`]: {
minWidth: 'max-content',
'&::after': {
content: 'none',
},
[`${progressCls}-text-inner`]: {
color: token.colorWhite,
[`&${progressCls}-text-bright`]: {
color: 'rgba(0, 0, 0, 0.45)',
},
},
},
},
[`${progressCls}-success-bg`]: {
@ -143,10 +161,10 @@ const genBaseStyle: GenerateStyle<ProgressToken> = (token) => {
[`${progressCls}-text`]: {
display: 'inline-block',
width: '2em',
marginInlineStart: token.marginXS,
color: token.colorText,
lineHeight: 1,
width: '2em',
whiteSpace: 'nowrap',
textAlign: 'start',
verticalAlign: 'middle',
@ -154,6 +172,30 @@ const genBaseStyle: GenerateStyle<ProgressToken> = (token) => {
[iconPrefixCls]: {
fontSize: token.fontSize,
},
[`&${progressCls}-text-outer`]: {
width: 'max-content',
},
[`&${progressCls}-text-outer${progressCls}-text-start`]: {
width: 'max-content',
marginInlineStart: 0,
marginInlineEnd: token.marginXS,
},
},
[`${progressCls}-text-inner`]: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
width: '100%',
height: '100%',
marginInlineStart: 0,
padding: `0 ${token.paddingXXS}`,
[`&${progressCls}-text-start`]: {
justifyContent: 'start',
},
[`&${progressCls}-text-end`]: {
justifyContent: 'end',
},
},
[`&${progressCls}-status-active`]: {