-
-
Notifications
You must be signed in to change notification settings - Fork 160
Expand file tree
/
Copy pathLine.tsx
More file actions
120 lines (111 loc) · 3.48 KB
/
Line.tsx
File metadata and controls
120 lines (111 loc) · 3.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import * as React from 'react';
import classNames from 'classnames';
import { useTransitionDuration, defaultProps } from './common';
import type { ProgressProps } from './interface';
import getIndeterminateLine from './utils/getIndeterminateLine';
import useId from '@rc-component/util/lib/hooks/useId';
const Line: React.FC<ProgressProps> = (props) => {
const {
id,
className,
percent,
prefixCls,
strokeColor,
strokeLinecap,
strokeWidth,
style,
railColor,
railWidth,
transition,
loading,
...restProps
} = {
...defaultProps,
...props,
};
const mergedId = useId(id);
// eslint-disable-next-line no-param-reassign
delete restProps.gapPosition;
const percentList = Array.isArray(percent) ? percent : [percent];
const strokeColorList = Array.isArray(strokeColor) ? strokeColor : [strokeColor];
const paths = useTransitionDuration();
const center = strokeWidth / 2;
const right = 100 - strokeWidth / 2;
const pathString = `M ${strokeLinecap === 'round' ? center : 0},${center}
L ${strokeLinecap === 'round' ? right : 100},${center}`;
const viewBoxString = `0 0 100 ${strokeWidth}`;
let stackPtg = 0;
const { indeterminateStyleProps, indeterminateStyleAnimation } = getIndeterminateLine({
id: mergedId,
loading,
percent: percentList[0],
strokeLinecap,
strokeWidth,
});
return (
<svg
className={classNames(`${prefixCls}-line`, className)}
viewBox={viewBoxString}
preserveAspectRatio="none"
style={style}
{...restProps}
>
<path
className={`${prefixCls}-line-rail`}
d={pathString}
strokeLinecap={strokeLinecap}
stroke={railColor}
strokeWidth={railWidth || strokeWidth}
fillOpacity="0"
/>
{percentList.map((ptg, index) => {
let dashPercent = 1;
switch (strokeLinecap) {
case 'round':
dashPercent = 1 - strokeWidth / 100;
break;
case 'square':
dashPercent = 1 - strokeWidth / 2 / 100;
break;
default:
dashPercent = 1;
break;
}
const pathStyle: React.CSSProperties = {
strokeDasharray: `${ptg * dashPercent}px, 100px`,
strokeDashoffset: `-${stackPtg}px`,
transition:
transition ||
'stroke-dashoffset 0.3s ease 0s, stroke-dasharray .3s ease 0s, stroke 0.3s linear',
...indeterminateStyleProps,
};
const color = strokeColorList[index] || strokeColorList[strokeColorList.length - 1];
stackPtg += ptg;
return (
<path
key={index}
className={`${prefixCls}-line-path`}
d={pathString}
strokeLinecap={strokeLinecap}
stroke={color as string}
strokeWidth={strokeWidth}
fillOpacity="0"
ref={(elem) => {
// https://reactjs.org/docs/refs-and-the-dom.html#callback-refs
// React will call the ref callback with the DOM element when the component mounts,
// and call it with `null` when it unmounts.
// Refs are guaranteed to be up-to-date before componentDidMount or componentDidUpdate fires.
paths[index] = elem;
}}
style={pathStyle}
/>
);
})}
{indeterminateStyleAnimation}
</svg>
);
};
if (process.env.NODE_ENV !== 'production') {
Line.displayName = 'Line';
}
export default Line;