Skip to content

Commit

Permalink
feat(progress): add circle progress
Browse files Browse the repository at this point in the history
feat(snapshot): update snapshot

feat(progress): update circleprogress

feat(progress): improve code
  • Loading branch information
窦婷婷 committed Aug 2, 2023
1 parent 93714ed commit 5afefcb
Show file tree
Hide file tree
Showing 11 changed files with 763 additions and 7 deletions.
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -73,6 +73,7 @@
"rc-animate": "2",
"rc-dialog": "7.7.0",
"rc-form": "2.4.12",
"rc-progress": "^3.4.2",
"rc-slider": "8.6.13",
"rc-util": "4.21.1",
"react-lifecycles-compat": "^3.0.4",
Expand Down
97 changes: 97 additions & 0 deletions src/components/Progress/CircleProgress.jsx
@@ -0,0 +1,97 @@
import React, { useCallback, useEffect, useMemo, useRef } from 'react';
import PropTypes from 'prop-types';
import { Circle as RCCircle } from 'rc-progress';
import useDesignTokens from 'src/components/ThemeProvider/useDesignTokens';
import Tooltip from 'src/components/Tooltip';
import { CircleWrapper, CircleText } from './style';

const CircleProgress = ({ format, percent, strokeWidth = 10, color, style = {}, ...rest }) => {
const DT = useDesignTokens();
const circleWrapperRef = useRef(null);
const [width, setWidth] = React.useState();

const getStrokeColor = useCallback(
color => {
switch (color) {
case 'success':
return DT.T_COLOR_BG_SUCCESS_DARK;
case 'warn':
return DT.T_COLOR_BG_WARNING_DARK;
case 'error':
return DT.T_COLOR_BG_ERROR_DARK;
case 'default':
return DT.T_COLOR_BG_PRIMARY_1;
default:
return color || DT.T_COLOR_BG_PRIMARY_1;
}
},
[DT]
);

useEffect(() => {
const circleWrapper = circleWrapperRef.current;
if (circleWrapper) {
setWidth(circleWrapper.clientWidth);
}
}, [circleWrapperRef]);

const _strokeWidth = useMemo(() => {
// rc-progress 环形进度条的 strokeWidth 是相对于环形的宽度的,想要任意 width 的环形进度条都是同样的粗细,需要计算出相对于 100px 宽度的 strokeWidth
return width ? strokeWidth * (100 / width) : strokeWidth;
}, [strokeWidth, width]);

const circleContent = (
<RCCircle
percent={percent}
strokeWidth={_strokeWidth}
trailWidth={_strokeWidth}
strokeColor={getStrokeColor(color)}
trailColor={DT.T_PROGRESS_COLOR_BG_DEFAULT}
/>
);

const FormatInfo = () => {
return format !== null && <CircleText>{format(percent)}</CircleText>;
};

return (
<CircleWrapper ref={circleWrapperRef} style={{ ...style, height: width }} {...rest}>
{width <= 36 ? (
format ? (
<Tooltip popup={<FormatInfo />}>
<span>{circleContent}</span>
</Tooltip>
) : (
circleContent
)
) : (
<>
{circleContent}
{<FormatInfo />}
</>
)}
</CircleWrapper>
);
};

CircleProgress.propTypes = {
/** 当前百分比 */
percent: PropTypes.number,
/** 进度条颜色,内置 success、warn、error */
color: PropTypes.oneOfType([PropTypes.oneOf(['success', 'warn', 'error']), PropTypes.string]),
/**
* 展示文字的格式化,为 null 时隐藏文字
* @argument percent - 格式化的百分比
*/
format: PropTypes.func,
/**
* 进度条粗度
*/
strokeWidth: PropTypes.number,
/**
* @ignore 样式
*/
style: PropTypes.object
};

export default CircleProgress;
23 changes: 20 additions & 3 deletions src/components/Progress/Progress.jsx
Expand Up @@ -2,9 +2,14 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types';

import { Outer, Inner, TextWrap, EndText, CurrentText } from './style';
import CircleProgress from './CircleProgress';

class Progress extends Component {
static propTypes = {
/**
* 进度条类型,可选 line、circle
*/
styleType: PropTypes.oneOf(['line', 'circle']),
/** 当前百分比 */
percent: PropTypes.number,
/** 进度条颜色,内置 success、warn、error */
Expand All @@ -13,23 +18,35 @@ class Progress extends Component {
* 展示文字的格式化,为 null 时隐藏文字
* @argument percent - 格式化的百分比
*/
format: PropTypes.func
format: PropTypes.func,
/**
* 进度条粗度
*/
strokeWidth: PropTypes.number
};
static defaultProps = {
styleType: 'line',
percent: 0,
strokeWidth: 10,
format: percent => `${percent}%`
};
render() {
let { percent, format, color, ...rest } = this.props;
let { styleType, percent, format, color, strokeWidth, ...rest } = this.props;
percent = (percent < 0 ? 0 : percent > 100 ? 100 : percent) >> 0;

if (styleType === 'circle') {
return (
<CircleProgress percent={percent} format={format} color={color} strokeWidth={strokeWidth} {...rest} />
);
}
return (
<div {...rest}>
{format !== null && (
<TextWrap>
<CurrentText percent={percent}>{format(percent)}</CurrentText>
</TextWrap>
)}
<Outer>
<Outer strokeWidth={strokeWidth}>
<Inner color={color} percent={percent} />
</Outer>
{format !== null && (
Expand Down
3 changes: 3 additions & 0 deletions src/components/Progress/__demo__/base.jsx
Expand Up @@ -36,6 +36,9 @@ class Demo extends React.Component {
<div className="demo-wrap" style={{ padding: 24 }}>
<Progress percent={percent} />
</div>
<div className="demo-wrap" style={{ padding: 24, width: 100 }}>
<Progress percent={percent} styleType="circle" />
</div>
</div>
);
}
Expand Down
10 changes: 10 additions & 0 deletions src/components/Progress/__demo__/color.jsx
@@ -1,6 +1,7 @@
import React from 'react';

import Progress from 'src/components/Progress';
import Combine from 'src/components/Combine';

// demo start
class Demo extends React.Component {
Expand All @@ -25,6 +26,15 @@ class Demo extends React.Component {
<div className="demo-wrap" style={{ padding: 24 }}>
<Progress percent={67} color="#411" />
</div>
<div className="demo-wrap" style={{ padding: 24 }}>
<Combine>
<Progress percent={40} styleType="circle" style={{ width: 100 }} />
<Progress percent={100} color="success" styleType="circle" style={{ width: 100 }} />
<Progress percent={20} color="warn" styleType="circle" style={{ width: 100 }} />
<Progress percent={50} color="error" styleType="circle" style={{ width: 100 }} />
<Progress percent={67} color="#411" styleType="circle" style={{ width: 100 }} />
</Combine>
</div>
</div>
);
}
Expand Down
3 changes: 3 additions & 0 deletions src/components/Progress/__demo__/custom.jsx
Expand Up @@ -29,6 +29,9 @@ class Demo extends React.Component {
<Progress percent={40} format={null} style={{ width: 100 }} />
</Tooltip>
</div>
<div className="demo-wrap" style={{ padding: 24 }}>
<Progress percent={40} format={null} style={{ width: 100 }} styleType="circle" />
</div>
</div>
);
}
Expand Down
7 changes: 7 additions & 0 deletions src/components/Progress/__demo__/format.jsx
Expand Up @@ -39,6 +39,13 @@ class Demo extends React.Component {
<div className="demo-wrap" style={{ padding: 24 }}>
<Progress percent={percent} format={null} />
</div>

<div className="demo-wrap" style={{ padding: 24, width: 100 }}>
<Progress percent={percent} format={v => `${v.toFixed(2)}%`} styleType="circle" />
</div>
<div className="demo-wrap" style={{ padding: 24, width: 100 }}>
<Progress percent={percent} format={null} styleType="circle" />
</div>
</div>
);
}
Expand Down

0 comments on commit 5afefcb

Please sign in to comment.