diff --git a/components/progress/progress.tsx b/components/progress/progress.tsx
index e8fdd7aa43..f51340a049 100644
--- a/components/progress/progress.tsx
+++ b/components/progress/progress.tsx
@@ -12,10 +12,13 @@ import useConfigInject from '../config-provider/hooks/useConfigInject';
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 },
name: 'AProgress',
+ inheritAttrs: false,
props: initDefaultProps(progressProps(), {
type: 'line',
percent: 0,
@@ -26,8 +29,9 @@ export default defineComponent({
strokeLinecap: 'round',
}),
slots: ['format'],
- setup(props, { slots }) {
+ setup(props, { slots, attrs }) {
const { prefixCls, direction } = useConfigInject('progress', props);
+ const [wrapSSR, hashId] = useStyle(prefixCls);
devWarning(
props.successPercent == undefined,
'Progress',
@@ -37,6 +41,7 @@ export default defineComponent({
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,
@@ -93,6 +98,7 @@ export default defineComponent({
return () => {
const { type, steps, strokeColor, title } = props;
+ const { class: cls, ...restAttrs } = attrs;
const progressInfo = renderProcessInfo();
let progress: VueNode;
@@ -120,15 +126,14 @@ export default defineComponent({
);
}
- const classNames = {
- ...classString.value,
+ const classes = classNames(classString.value, {
[`${prefixCls.value}-status-${progressStatus.value}`]: true,
- };
+ });
- return (
-
+ return wrapSSR(
+
{progress}
-
+
,
);
};
},
diff --git a/components/progress/style/index.less b/components/progress/style/index.less
deleted file mode 100644
index 9ba9914378..0000000000
--- a/components/progress/style/index.less
+++ /dev/null
@@ -1,210 +0,0 @@
-@import '../../style/themes/index';
-@import '../../style/mixins/index';
-
-@progress-prefix-cls: ~'@{ant-prefix}-progress';
-
-.@{progress-prefix-cls} {
- .reset-component();
-
- display: inline-block;
-
- &-line {
- position: relative;
- width: 100%;
- 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;
- }
-
- &-outer {
- display: inline-block;
- width: 100%;
- margin-right: 0;
- padding-right: 0;
- .@{progress-prefix-cls}-show-info & {
- margin-right: ~'calc(-2em - 8px)';
- padding-right: ~'calc(2em + 8px)';
- }
- }
-
- &-inner {
- position: relative;
- display: inline-block;
- width: 100%;
- overflow: hidden;
- vertical-align: middle;
- background-color: @progress-remaining-color;
- border-radius: @progress-radius;
- }
-
- &-circle-trail {
- stroke: @progress-remaining-color;
- }
-
- &-circle-path {
- animation: ~'@{ant-prefix}-progress-appear' 0.3s;
- }
-
- &-inner:not(.@{ant-prefix}-progress-circle-gradient) {
- .@{ant-prefix}-progress-circle-path {
- stroke: @progress-default-color;
- }
- }
-
- &-success-bg,
- &-bg {
- position: relative;
- background-color: @progress-default-color;
- border-radius: @progress-radius;
- transition: all 0.4s @ease-out-circ 0s;
- }
-
- &-success-bg {
- position: absolute;
- top: 0;
- left: 0;
- background-color: @success-color;
- }
-
- &-text {
- display: inline-block;
- width: 2em;
- margin-left: 8px;
- color: @progress-info-text-color;
- font-size: @progress-text-font-size;
- line-height: 1;
- white-space: nowrap;
- text-align: left;
- vertical-align: middle;
- word-break: normal;
- .@{iconfont-css-prefix} {
- font-size: @font-size-base;
- }
- }
-
- &-status-active {
- .@{progress-prefix-cls}-bg::before {
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- background: @component-background;
- border-radius: 10px;
- opacity: 0;
- animation: ~'@{ant-prefix}-progress-active' 2.4s @ease-out-quint infinite;
- content: '';
- }
- }
-
- &-status-exception {
- .@{progress-prefix-cls}-bg {
- background-color: @error-color;
- }
- .@{progress-prefix-cls}-text {
- color: @error-color;
- }
- }
-
- &-status-exception &-inner:not(.@{progress-prefix-cls}-circle-gradient) {
- .@{progress-prefix-cls}-circle-path {
- stroke: @error-color;
- }
- }
-
- &-status-success {
- .@{progress-prefix-cls}-bg {
- background-color: @success-color;
- }
- .@{progress-prefix-cls}-text {
- color: @success-color;
- }
- }
-
- &-status-success &-inner:not(.@{progress-prefix-cls}-circle-gradient) {
- .@{progress-prefix-cls}-circle-path {
- stroke: @success-color;
- }
- }
-
- &-circle &-inner {
- position: relative;
- line-height: 1;
- background-color: transparent;
- }
-
- &-circle &-text {
- position: absolute;
- top: 50%;
- left: 50%;
- width: 100%;
- margin: 0;
- padding: 0;
- color: @progress-text-color;
- font-size: @progress-circle-text-font-size;
- line-height: 1;
- white-space: normal;
- text-align: center;
- transform: translate(-50%, -50%);
-
- .@{iconfont-css-prefix} {
- font-size: (14 / 12em);
- }
- }
-
- &-circle&-status-exception {
- .@{progress-prefix-cls}-text {
- color: @error-color;
- }
- }
-
- &-circle&-status-success {
- .@{progress-prefix-cls}-text {
- color: @success-color;
- }
- }
-}
-
-@keyframes ~"@{ant-prefix}-progress-active" {
- 0% {
- transform: translateX(-100%) scaleX(0);
- opacity: 0.1;
- }
-
- 20% {
- transform: translateX(-100%) scaleX(0);
- opacity: 0.5;
- }
-
- 100% {
- transform: translateX(0) scaleX(1);
- opacity: 0;
- }
-}
-
-@import './rtl';
diff --git a/components/progress/style/index.ts b/components/progress/style/index.ts
new file mode 100644
index 0000000000..76a210e71e
--- /dev/null
+++ b/components/progress/style/index.ts
@@ -0,0 +1,274 @@
+import type { CSSObject } from '../../_util/cssinjs';
+import { Keyframes } from '../../_util/cssinjs';
+import type { FullToken, GenerateStyle } from '../../theme/internal';
+import { genComponentStyleHook, mergeToken } from '../../theme/internal';
+import { resetComponent } from '../../_style';
+
+export interface ComponentToken {}
+
+interface ProgressToken extends FullToken<'Progress'> {
+ progressLineRadius: number;
+ progressInfoTextColor: string;
+ progressRemainingColor: string;
+ progressDefaultColor: string;
+ progressStepMinWidth: number;
+ progressStepMarginInlineEnd: number;
+ progressActiveMotionDuration: string;
+}
+
+const antProgressActive = new Keyframes('antProgressActive', {
+ '0%': {
+ transform: 'translateX(-100%) scaleX(0)',
+ opacity: 0.1,
+ },
+ '20%': {
+ transform: 'translateX(-100%) scaleX(0)',
+ opacity: 0.5,
+ },
+ to: {
+ transform: 'translateX(0) scaleX(1)',
+ opacity: 0,
+ },
+});
+
+const genBaseStyle: GenerateStyle = token => {
+ const { componentCls: progressCls, iconCls: iconPrefixCls } = token;
+
+ return {
+ [progressCls]: {
+ ...resetComponent(token),
+
+ display: 'inline-block',
+
+ '&-rtl': {
+ direction: 'rtl',
+ },
+
+ '&-line': {
+ position: 'relative',
+ width: '100%',
+ fontSize: token.fontSize,
+ marginInlineEnd: token.marginXS,
+ marginBottom: token.marginXS,
+ },
+
+ [`${progressCls}-outer`]: {
+ display: 'inline-block',
+ width: '100%',
+ },
+
+ [`&${progressCls}-show-info`]: {
+ [`${progressCls}-outer`]: {
+ marginInlineEnd: `calc(-2em - ${token.marginXS}px)`,
+ paddingInlineEnd: `calc(2em + ${token.paddingXS}px)`,
+ },
+ },
+
+ [`${progressCls}-inner`]: {
+ position: 'relative',
+ display: 'inline-block',
+ width: '100%',
+ overflow: 'hidden',
+ verticalAlign: 'middle',
+ backgroundColor: token.progressRemainingColor,
+ borderRadius: token.progressLineRadius,
+ },
+
+ [`${progressCls}-inner:not(${progressCls}-circle-gradient)`]: {
+ [`${progressCls}-circle-path`]: {
+ stroke: token.colorInfo,
+ },
+ },
+
+ [`${progressCls}-success-bg, ${progressCls}-bg`]: {
+ position: 'relative',
+ backgroundColor: token.colorInfo,
+ borderRadius: token.progressLineRadius,
+ transition: `all ${token.motionDurationSlow} ${token.motionEaseInOutCirc}`,
+ },
+
+ [`${progressCls}-success-bg`]: {
+ position: 'absolute',
+ insetBlockStart: 0,
+ insetInlineStart: 0,
+ backgroundColor: token.colorSuccess,
+ },
+
+ [`${progressCls}-text`]: {
+ display: 'inline-block',
+ width: '2em',
+ marginInlineStart: token.marginXS,
+ color: token.progressInfoTextColor,
+ lineHeight: 1,
+ whiteSpace: 'nowrap',
+ textAlign: 'start',
+ verticalAlign: 'middle',
+ wordBreak: 'normal',
+ [iconPrefixCls]: {
+ fontSize: token.fontSize,
+ },
+ },
+
+ [`&${progressCls}-status-active`]: {
+ [`${progressCls}-bg::before`]: {
+ position: 'absolute',
+ inset: 0,
+ backgroundColor: token.colorBgContainer,
+ borderRadius: token.progressLineRadius,
+ opacity: 0,
+ animationName: antProgressActive,
+ animationDuration: token.progressActiveMotionDuration,
+ animationTimingFunction: token.motionEaseOutQuint,
+ animationIterationCount: 'infinite',
+ content: '""',
+ },
+ },
+
+ [`&${progressCls}-status-exception`]: {
+ [`${progressCls}-bg`]: {
+ backgroundColor: token.colorError,
+ },
+ [`${progressCls}-text`]: {
+ color: token.colorError,
+ },
+ },
+
+ [`&${progressCls}-status-exception ${progressCls}-inner:not(${progressCls}-circle-gradient)`]:
+ {
+ [`${progressCls}-circle-path`]: {
+ stroke: token.colorError,
+ },
+ },
+
+ [`&${progressCls}-status-success`]: {
+ [`${progressCls}-bg`]: {
+ backgroundColor: token.colorSuccess,
+ },
+ [`${progressCls}-text`]: {
+ color: token.colorSuccess,
+ },
+ },
+
+ [`&${progressCls}-status-success ${progressCls}-inner:not(${progressCls}-circle-gradient)`]: {
+ [`${progressCls}-circle-path`]: {
+ stroke: token.colorSuccess,
+ },
+ },
+ },
+ };
+};
+
+const genCircleStyle: GenerateStyle = token => {
+ const { componentCls: progressCls, iconCls: iconPrefixCls } = token;
+
+ return {
+ [progressCls]: {
+ [`${progressCls}-circle-trail`]: {
+ stroke: token.progressRemainingColor,
+ },
+
+ [`&${progressCls}-circle ${progressCls}-inner`]: {
+ position: 'relative',
+ lineHeight: 1,
+ backgroundColor: 'transparent',
+ },
+
+ [`&${progressCls}-circle ${progressCls}-text`]: {
+ position: 'absolute',
+ insetBlockStart: '50%',
+ insetInlineStart: 0,
+ width: '100%',
+ margin: 0,
+ padding: 0,
+ color: token.colorText,
+ lineHeight: 1,
+ whiteSpace: 'normal',
+ textAlign: 'center',
+ transform: 'translateY(-50%)',
+
+ [iconPrefixCls]: {
+ fontSize: `${token.fontSize / token.fontSizeSM}em`,
+ },
+ },
+
+ [`${progressCls}-circle&-status-exception`]: {
+ [`${progressCls}-text`]: {
+ color: token.colorError,
+ },
+ },
+
+ [`${progressCls}-circle&-status-success`]: {
+ [`${progressCls}-text`]: {
+ color: token.colorSuccess,
+ },
+ },
+ },
+ [`${progressCls}-inline-circle`]: {
+ lineHeight: 1,
+ [`${progressCls}-inner`]: {
+ verticalAlign: 'bottom',
+ },
+ },
+ };
+};
+
+const genStepStyle: GenerateStyle = (token: ProgressToken): CSSObject => {
+ const { componentCls: progressCls } = token;
+
+ return {
+ [progressCls]: {
+ [`${progressCls}-steps`]: {
+ display: 'inline-block',
+ '&-outer': {
+ display: 'flex',
+ flexDirection: 'row',
+ alignItems: 'center',
+ },
+ '&-item': {
+ flexShrink: 0,
+ minWidth: token.progressStepMinWidth,
+ marginInlineEnd: token.progressStepMarginInlineEnd,
+ backgroundColor: token.progressRemainingColor,
+ transition: `all ${token.motionDurationSlow}`,
+
+ '&-active': {
+ backgroundColor: token.colorInfo,
+ },
+ },
+ },
+ },
+ };
+};
+
+const genSmallLine: GenerateStyle = (token: ProgressToken): CSSObject => {
+ const { componentCls: progressCls, iconCls: iconPrefixCls } = token;
+
+ return {
+ [progressCls]: {
+ [`${progressCls}-small&-line, ${progressCls}-small&-line ${progressCls}-text ${iconPrefixCls}`]:
+ {
+ fontSize: token.fontSizeSM,
+ },
+ },
+ };
+};
+
+export default genComponentStyleHook('Progress', token => {
+ const progressStepMarginInlineEnd = token.marginXXS / 2;
+
+ const progressToken = mergeToken(token, {
+ progressLineRadius: 100, // magic for capsule shape, should be a very large number
+ progressInfoTextColor: token.colorText,
+ progressDefaultColor: token.colorInfo,
+ progressRemainingColor: token.colorFillSecondary,
+ progressStepMarginInlineEnd,
+ progressStepMinWidth: progressStepMarginInlineEnd,
+ progressActiveMotionDuration: '2.4s',
+ });
+ return [
+ genBaseStyle(progressToken),
+ genCircleStyle(progressToken),
+ genStepStyle(progressToken),
+ genSmallLine(progressToken),
+ ];
+});
diff --git a/components/progress/style/index.tsx b/components/progress/style/index.tsx
deleted file mode 100644
index 3a3ab0de59..0000000000
--- a/components/progress/style/index.tsx
+++ /dev/null
@@ -1,2 +0,0 @@
-import '../../style/index.less';
-import './index.less';
diff --git a/components/progress/style/rtl.less b/components/progress/style/rtl.less
deleted file mode 100644
index 0756b5f847..0000000000
--- a/components/progress/style/rtl.less
+++ /dev/null
@@ -1,37 +0,0 @@
-@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/style.ts b/components/style.ts
index 338d6438b8..0ab8e11ce1 100644
--- a/components/style.ts
+++ b/components/style.ts
@@ -38,7 +38,7 @@ import './calendar/style';
import './date-picker/style';
import './slider/style';
import './table/style';
-import './progress/style';
+// import './progress/style';
import './timeline/style';
import './input-number/style';
import './transfer/style';
diff --git a/components/theme/interface/components.ts b/components/theme/interface/components.ts
index 8e7a5bf3cb..be28a99e60 100644
--- a/components/theme/interface/components.ts
+++ b/components/theme/interface/components.ts
@@ -26,7 +26,7 @@ import type { ComponentToken as ModalComponentToken } from '../../modal/style';
import type { ComponentToken as NotificationComponentToken } from '../../notification/style';
import type { ComponentToken as PopconfirmComponentToken } from '../../popconfirm/style';
import type { ComponentToken as PopoverComponentToken } from '../../popover/style';
-// import type { ComponentToken as ProgressComponentToken } from '../../progress/style';
+import type { ComponentToken as ProgressComponentToken } from '../../progress/style';
// import type { ComponentToken as RadioComponentToken } from '../../radio/style';
// import type { ComponentToken as RateComponentToken } from '../../rate/style';
// import type { ComponentToken as ResultComponentToken } from '../../result/style';
@@ -109,7 +109,7 @@ export interface ComponentTokenMap {
Tooltip?: TooltipComponentToken;
// Table?: TableComponentToken;
// Space?: SpaceComponentToken;
- // Progress?: ProgressComponentToken;
+ Progress?: ProgressComponentToken;
// Tour?: TourComponentToken;
// QRCode?: QRCodeComponentToken;
// App?: AppComponentToken;