refactor: progress style (#6234)

* refactor: progress

* refactor: progress style

* fix: progress attrs
pull/6236/head
Zev Zhu 2023-02-07 10:25:02 +08:00 committed by GitHub
parent 81e26a900e
commit 2c1afa5e72
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 289 additions and 259 deletions

View File

@ -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 (
<div class={classNames} title={title}>
return wrapSSR(
<div {...restAttrs} class={[classes, cls]} title={title}>
{progress}
</div>
</div>,
);
};
},

View File

@ -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';

View File

@ -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<ProgressToken> = 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<ProgressToken> = 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<ProgressToken> = (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<ProgressToken> = (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<ProgressToken>(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),
];
});

View File

@ -1,2 +0,0 @@
import '../../style/index.less';
import './index.less';

View File

@ -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;
}
}
}

View File

@ -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';

View File

@ -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;