index.js 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. import { Keyframes, unit } from '@ant-design/cssinjs';
  2. import { resetComponent } from '../../style';
  3. import { genStyleHooks, mergeToken } from '../../theme/internal';
  4. export const LineStrokeColorVar = '--progress-line-stroke-color';
  5. export const Percent = '--progress-percent';
  6. const genAntProgressActive = isRtl => {
  7. const direction = isRtl ? '100%' : '-100%';
  8. return new Keyframes(`antProgress${isRtl ? 'RTL' : 'LTR'}Active`, {
  9. '0%': {
  10. transform: `translateX(${direction}) scaleX(0)`,
  11. opacity: 0.1
  12. },
  13. '20%': {
  14. transform: `translateX(${direction}) scaleX(0)`,
  15. opacity: 0.5
  16. },
  17. to: {
  18. transform: 'translateX(0) scaleX(1)',
  19. opacity: 0
  20. }
  21. });
  22. };
  23. const genBaseStyle = token => {
  24. const {
  25. componentCls: progressCls,
  26. iconCls: iconPrefixCls
  27. } = token;
  28. return {
  29. [progressCls]: Object.assign(Object.assign({}, resetComponent(token)), {
  30. display: 'inline-block',
  31. '&-rtl': {
  32. direction: 'rtl'
  33. },
  34. '&-line': {
  35. position: 'relative',
  36. width: '100%',
  37. fontSize: token.fontSize
  38. },
  39. [`${progressCls}-outer`]: {
  40. display: 'inline-flex',
  41. alignItems: 'center',
  42. width: '100%'
  43. },
  44. [`${progressCls}-inner`]: {
  45. position: 'relative',
  46. display: 'inline-block',
  47. width: '100%',
  48. flex: 1,
  49. overflow: 'hidden',
  50. verticalAlign: 'middle',
  51. backgroundColor: token.remainingColor,
  52. borderRadius: token.lineBorderRadius
  53. },
  54. [`${progressCls}-inner:not(${progressCls}-circle-gradient)`]: {
  55. [`${progressCls}-circle-path`]: {
  56. stroke: token.defaultColor
  57. }
  58. },
  59. [`${progressCls}-success-bg, ${progressCls}-bg`]: {
  60. position: 'relative',
  61. background: token.defaultColor,
  62. borderRadius: token.lineBorderRadius,
  63. transition: `all ${token.motionDurationSlow} ${token.motionEaseInOutCirc}`
  64. },
  65. [`${progressCls}-layout-bottom`]: {
  66. display: 'flex',
  67. flexDirection: 'column',
  68. alignItems: 'center',
  69. justifyContent: 'center',
  70. [`${progressCls}-text`]: {
  71. width: 'max-content',
  72. marginInlineStart: 0,
  73. marginTop: token.marginXXS
  74. }
  75. },
  76. [`${progressCls}-bg`]: {
  77. overflow: 'hidden',
  78. '&::after': {
  79. content: '""',
  80. background: {
  81. _multi_value_: true,
  82. value: ['inherit', `var(${LineStrokeColorVar})`]
  83. },
  84. height: '100%',
  85. width: `calc(1 / var(${Percent}) * 100%)`,
  86. display: 'block'
  87. },
  88. [`&${progressCls}-bg-inner`]: {
  89. minWidth: 'max-content',
  90. '&::after': {
  91. content: 'none'
  92. },
  93. [`${progressCls}-text-inner`]: {
  94. color: token.colorWhite,
  95. [`&${progressCls}-text-bright`]: {
  96. color: 'rgba(0, 0, 0, 0.45)'
  97. }
  98. }
  99. }
  100. },
  101. [`${progressCls}-success-bg`]: {
  102. position: 'absolute',
  103. insetBlockStart: 0,
  104. insetInlineStart: 0,
  105. backgroundColor: token.colorSuccess
  106. },
  107. [`${progressCls}-text`]: {
  108. display: 'inline-block',
  109. marginInlineStart: token.marginXS,
  110. color: token.colorText,
  111. lineHeight: 1,
  112. width: '2em',
  113. whiteSpace: 'nowrap',
  114. textAlign: 'start',
  115. verticalAlign: 'middle',
  116. wordBreak: 'normal',
  117. [iconPrefixCls]: {
  118. fontSize: token.fontSize
  119. },
  120. [`&${progressCls}-text-outer`]: {
  121. width: 'max-content'
  122. },
  123. [`&${progressCls}-text-outer${progressCls}-text-start`]: {
  124. width: 'max-content',
  125. marginInlineStart: 0,
  126. marginInlineEnd: token.marginXS
  127. }
  128. },
  129. [`${progressCls}-text-inner`]: {
  130. display: 'flex',
  131. justifyContent: 'center',
  132. alignItems: 'center',
  133. width: '100%',
  134. height: '100%',
  135. marginInlineStart: 0,
  136. padding: `0 ${unit(token.paddingXXS)}`,
  137. [`&${progressCls}-text-start`]: {
  138. justifyContent: 'start'
  139. },
  140. [`&${progressCls}-text-end`]: {
  141. justifyContent: 'end'
  142. }
  143. },
  144. [`&${progressCls}-status-active`]: {
  145. [`${progressCls}-bg::before`]: {
  146. position: 'absolute',
  147. inset: 0,
  148. backgroundColor: token.colorBgContainer,
  149. borderRadius: token.lineBorderRadius,
  150. opacity: 0,
  151. animationName: genAntProgressActive(),
  152. animationDuration: token.progressActiveMotionDuration,
  153. animationTimingFunction: token.motionEaseOutQuint,
  154. animationIterationCount: 'infinite',
  155. content: '""'
  156. }
  157. },
  158. [`&${progressCls}-rtl${progressCls}-status-active`]: {
  159. [`${progressCls}-bg::before`]: {
  160. animationName: genAntProgressActive(true)
  161. }
  162. },
  163. [`&${progressCls}-status-exception`]: {
  164. [`${progressCls}-bg`]: {
  165. backgroundColor: token.colorError
  166. },
  167. [`${progressCls}-text`]: {
  168. color: token.colorError
  169. }
  170. },
  171. [`&${progressCls}-status-exception ${progressCls}-inner:not(${progressCls}-circle-gradient)`]: {
  172. [`${progressCls}-circle-path`]: {
  173. stroke: token.colorError
  174. }
  175. },
  176. [`&${progressCls}-status-success`]: {
  177. [`${progressCls}-bg`]: {
  178. backgroundColor: token.colorSuccess
  179. },
  180. [`${progressCls}-text`]: {
  181. color: token.colorSuccess
  182. }
  183. },
  184. [`&${progressCls}-status-success ${progressCls}-inner:not(${progressCls}-circle-gradient)`]: {
  185. [`${progressCls}-circle-path`]: {
  186. stroke: token.colorSuccess
  187. }
  188. }
  189. })
  190. };
  191. };
  192. const genCircleStyle = token => {
  193. const {
  194. componentCls: progressCls,
  195. iconCls: iconPrefixCls
  196. } = token;
  197. return {
  198. [progressCls]: {
  199. [`${progressCls}-circle-trail`]: {
  200. stroke: token.remainingColor
  201. },
  202. [`&${progressCls}-circle ${progressCls}-inner`]: {
  203. position: 'relative',
  204. lineHeight: 1,
  205. backgroundColor: 'transparent'
  206. },
  207. [`&${progressCls}-circle ${progressCls}-text`]: {
  208. position: 'absolute',
  209. insetBlockStart: '50%',
  210. insetInlineStart: 0,
  211. width: '100%',
  212. margin: 0,
  213. padding: 0,
  214. color: token.circleTextColor,
  215. fontSize: token.circleTextFontSize,
  216. lineHeight: 1,
  217. whiteSpace: 'normal',
  218. textAlign: 'center',
  219. transform: 'translateY(-50%)',
  220. [iconPrefixCls]: {
  221. fontSize: token.circleIconFontSize
  222. }
  223. },
  224. [`${progressCls}-circle&-status-exception`]: {
  225. [`${progressCls}-text`]: {
  226. color: token.colorError
  227. }
  228. },
  229. [`${progressCls}-circle&-status-success`]: {
  230. [`${progressCls}-text`]: {
  231. color: token.colorSuccess
  232. }
  233. }
  234. },
  235. [`${progressCls}-inline-circle`]: {
  236. lineHeight: 1,
  237. [`${progressCls}-inner`]: {
  238. verticalAlign: 'bottom'
  239. }
  240. }
  241. };
  242. };
  243. const genStepStyle = token => {
  244. const {
  245. componentCls: progressCls
  246. } = token;
  247. return {
  248. [progressCls]: {
  249. [`${progressCls}-steps`]: {
  250. display: 'inline-block',
  251. '&-outer': {
  252. display: 'flex',
  253. flexDirection: 'row',
  254. alignItems: 'center'
  255. },
  256. '&-item': {
  257. flexShrink: 0,
  258. minWidth: token.progressStepMinWidth,
  259. marginInlineEnd: token.progressStepMarginInlineEnd,
  260. backgroundColor: token.remainingColor,
  261. transition: `all ${token.motionDurationSlow}`,
  262. '&-active': {
  263. backgroundColor: token.defaultColor
  264. }
  265. }
  266. }
  267. }
  268. };
  269. };
  270. const genSmallLine = token => {
  271. const {
  272. componentCls: progressCls,
  273. iconCls: iconPrefixCls
  274. } = token;
  275. return {
  276. [progressCls]: {
  277. [`${progressCls}-small&-line, ${progressCls}-small&-line ${progressCls}-text ${iconPrefixCls}`]: {
  278. fontSize: token.fontSizeSM
  279. }
  280. }
  281. };
  282. };
  283. export const prepareComponentToken = token => ({
  284. circleTextColor: token.colorText,
  285. defaultColor: token.colorInfo,
  286. remainingColor: token.colorFillSecondary,
  287. lineBorderRadius: 100,
  288. // magic for capsule shape, should be a very large number
  289. circleTextFontSize: '1em',
  290. circleIconFontSize: `${token.fontSize / token.fontSizeSM}em`
  291. });
  292. export default genStyleHooks('Progress', token => {
  293. const progressStepMarginInlineEnd = token.calc(token.marginXXS).div(2).equal();
  294. const progressToken = mergeToken(token, {
  295. progressStepMarginInlineEnd,
  296. progressStepMinWidth: progressStepMarginInlineEnd,
  297. progressActiveMotionDuration: '2.4s'
  298. });
  299. return [genBaseStyle(progressToken), genCircleStyle(progressToken), genStepStyle(progressToken), genSmallLine(progressToken)];
  300. }, prepareComponentToken);