index.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. import { unit } from '@ant-design/cssinjs';
  2. import { genFocusOutline, resetComponent } from '../../style';
  3. import { genStyleHooks, mergeToken } from '../../theme/internal';
  4. import genStepsCustomIconStyle from './custom-icon';
  5. import genStepsHorizontalStyle from './horizontal';
  6. import genStepsInlineStyle from './inline';
  7. import genStepsLabelPlacementStyle from './label-placement';
  8. import genStepsNavStyle from './nav';
  9. import genStepsProgressStyle from './progress';
  10. import genStepsProgressDotStyle from './progress-dot';
  11. import genStepsRTLStyle from './rtl';
  12. import genStepsSmallStyle from './small';
  13. import genStepsVerticalStyle from './vertical';
  14. const STEP_ITEM_STATUS_WAIT = 'wait';
  15. const STEP_ITEM_STATUS_PROCESS = 'process';
  16. const STEP_ITEM_STATUS_FINISH = 'finish';
  17. const STEP_ITEM_STATUS_ERROR = 'error';
  18. const genStepsItemStatusStyle = (status, token) => {
  19. const prefix = `${token.componentCls}-item`;
  20. const iconColorKey = `${status}IconColor`;
  21. const titleColorKey = `${status}TitleColor`;
  22. const descriptionColorKey = `${status}DescriptionColor`;
  23. const tailColorKey = `${status}TailColor`;
  24. const iconBgColorKey = `${status}IconBgColor`;
  25. const iconBorderColorKey = `${status}IconBorderColor`;
  26. const dotColorKey = `${status}DotColor`;
  27. return {
  28. [`${prefix}-${status} ${prefix}-icon`]: {
  29. backgroundColor: token[iconBgColorKey],
  30. borderColor: token[iconBorderColorKey],
  31. [`> ${token.componentCls}-icon`]: {
  32. color: token[iconColorKey],
  33. [`${token.componentCls}-icon-dot`]: {
  34. background: token[dotColorKey]
  35. }
  36. }
  37. },
  38. [`${prefix}-${status}${prefix}-custom ${prefix}-icon`]: {
  39. [`> ${token.componentCls}-icon`]: {
  40. color: token[dotColorKey]
  41. }
  42. },
  43. [`${prefix}-${status} > ${prefix}-container > ${prefix}-content > ${prefix}-title`]: {
  44. color: token[titleColorKey],
  45. '&::after': {
  46. backgroundColor: token[tailColorKey]
  47. }
  48. },
  49. [`${prefix}-${status} > ${prefix}-container > ${prefix}-content > ${prefix}-description`]: {
  50. color: token[descriptionColorKey]
  51. },
  52. [`${prefix}-${status} > ${prefix}-container > ${prefix}-tail::after`]: {
  53. backgroundColor: token[tailColorKey]
  54. }
  55. };
  56. };
  57. const genStepsItemStyle = token => {
  58. const {
  59. componentCls,
  60. motionDurationSlow
  61. } = token;
  62. const stepsItemCls = `${componentCls}-item`; // .ant-steps-item
  63. const stepItemIconCls = `${stepsItemCls}-icon`;
  64. return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({
  65. [stepsItemCls]: {
  66. position: 'relative',
  67. display: 'inline-block',
  68. flex: 1,
  69. overflow: 'hidden',
  70. verticalAlign: 'top',
  71. '&:last-child': {
  72. flex: 'none',
  73. [`> ${stepsItemCls}-container > ${stepsItemCls}-tail, > ${stepsItemCls}-container > ${stepsItemCls}-content > ${stepsItemCls}-title::after`]: {
  74. display: 'none'
  75. }
  76. }
  77. },
  78. [`${stepsItemCls}-container`]: {
  79. outline: 'none',
  80. [`&:focus-visible ${stepItemIconCls}`]: genFocusOutline(token)
  81. },
  82. [`${stepItemIconCls}, ${stepsItemCls}-content`]: {
  83. display: 'inline-block',
  84. verticalAlign: 'top'
  85. },
  86. [stepItemIconCls]: {
  87. width: token.iconSize,
  88. height: token.iconSize,
  89. marginTop: 0,
  90. marginBottom: 0,
  91. marginInlineStart: 0,
  92. marginInlineEnd: token.marginXS,
  93. fontSize: token.iconFontSize,
  94. fontFamily: token.fontFamily,
  95. lineHeight: unit(token.iconSize),
  96. textAlign: 'center',
  97. borderRadius: token.iconSize,
  98. border: `${unit(token.lineWidth)} ${token.lineType} transparent`,
  99. transition: `background-color ${motionDurationSlow}, border-color ${motionDurationSlow}`,
  100. [`${componentCls}-icon`]: {
  101. position: 'relative',
  102. top: token.iconTop,
  103. color: token.colorPrimary,
  104. lineHeight: 1
  105. }
  106. },
  107. [`${stepsItemCls}-tail`]: {
  108. position: 'absolute',
  109. top: token.calc(token.iconSize).div(2).equal(),
  110. insetInlineStart: 0,
  111. width: '100%',
  112. '&::after': {
  113. display: 'inline-block',
  114. width: '100%',
  115. height: token.lineWidth,
  116. background: token.colorSplit,
  117. borderRadius: token.lineWidth,
  118. transition: `background ${motionDurationSlow}`,
  119. content: '""'
  120. }
  121. },
  122. [`${stepsItemCls}-title`]: {
  123. position: 'relative',
  124. display: 'inline-block',
  125. paddingInlineEnd: token.padding,
  126. color: token.colorText,
  127. fontSize: token.fontSizeLG,
  128. lineHeight: unit(token.titleLineHeight),
  129. '&::after': {
  130. position: 'absolute',
  131. top: token.calc(token.titleLineHeight).div(2).equal(),
  132. insetInlineStart: '100%',
  133. display: 'block',
  134. width: 9999,
  135. height: token.lineWidth,
  136. background: token.processTailColor,
  137. content: '""'
  138. }
  139. },
  140. [`${stepsItemCls}-subtitle`]: {
  141. display: 'inline',
  142. marginInlineStart: token.marginXS,
  143. color: token.colorTextDescription,
  144. fontWeight: 'normal',
  145. fontSize: token.fontSize
  146. },
  147. [`${stepsItemCls}-description`]: {
  148. color: token.colorTextDescription,
  149. fontSize: token.fontSize
  150. }
  151. }, genStepsItemStatusStyle(STEP_ITEM_STATUS_WAIT, token)), genStepsItemStatusStyle(STEP_ITEM_STATUS_PROCESS, token)), {
  152. [`${stepsItemCls}-process > ${stepsItemCls}-container > ${stepsItemCls}-title`]: {
  153. fontWeight: token.fontWeightStrong
  154. }
  155. }), genStepsItemStatusStyle(STEP_ITEM_STATUS_FINISH, token)), genStepsItemStatusStyle(STEP_ITEM_STATUS_ERROR, token)), {
  156. [`${stepsItemCls}${componentCls}-next-error > ${componentCls}-item-title::after`]: {
  157. background: token.colorError
  158. },
  159. [`${stepsItemCls}-disabled`]: {
  160. cursor: 'not-allowed'
  161. }
  162. });
  163. };
  164. // ============================= Clickable ===========================
  165. const genStepsClickableStyle = token => {
  166. const {
  167. componentCls,
  168. motionDurationSlow
  169. } = token;
  170. return {
  171. [`& ${componentCls}-item`]: {
  172. [`&:not(${componentCls}-item-active)`]: {
  173. [`& > ${componentCls}-item-container[role='button']`]: {
  174. cursor: 'pointer',
  175. [`${componentCls}-item`]: {
  176. [`&-title, &-subtitle, &-description, &-icon ${componentCls}-icon`]: {
  177. transition: `color ${motionDurationSlow}`
  178. }
  179. },
  180. '&:hover': {
  181. [`${componentCls}-item`]: {
  182. '&-title, &-subtitle, &-description': {
  183. color: token.colorPrimary
  184. }
  185. }
  186. }
  187. },
  188. [`&:not(${componentCls}-item-process)`]: {
  189. [`& > ${componentCls}-item-container[role='button']:hover`]: {
  190. [`${componentCls}-item`]: {
  191. '&-icon': {
  192. borderColor: token.colorPrimary,
  193. [`${componentCls}-icon`]: {
  194. color: token.colorPrimary
  195. }
  196. }
  197. }
  198. }
  199. }
  200. }
  201. },
  202. [`&${componentCls}-horizontal:not(${componentCls}-label-vertical)`]: {
  203. [`${componentCls}-item`]: {
  204. paddingInlineStart: token.padding,
  205. whiteSpace: 'nowrap',
  206. '&:first-child': {
  207. paddingInlineStart: 0
  208. },
  209. [`&:last-child ${componentCls}-item-title`]: {
  210. paddingInlineEnd: 0
  211. },
  212. '&-tail': {
  213. display: 'none'
  214. },
  215. '&-description': {
  216. maxWidth: token.descriptionMaxWidth,
  217. whiteSpace: 'normal'
  218. }
  219. }
  220. }
  221. };
  222. };
  223. const genStepsStyle = token => {
  224. const {
  225. componentCls
  226. } = token; // .ant-steps
  227. return {
  228. [componentCls]: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, resetComponent(token)), {
  229. display: 'flex',
  230. width: '100%',
  231. fontSize: 0,
  232. textAlign: 'initial'
  233. }), genStepsItemStyle(token)), genStepsClickableStyle(token)), genStepsCustomIconStyle(token)), genStepsSmallStyle(token)), genStepsVerticalStyle(token)), genStepsHorizontalStyle(token)), genStepsLabelPlacementStyle(token)), genStepsProgressDotStyle(token)), genStepsNavStyle(token)), genStepsRTLStyle(token)), genStepsProgressStyle(token)), genStepsInlineStyle(token))
  234. };
  235. };
  236. // ============================== Export ==============================
  237. export const prepareComponentToken = token => ({
  238. titleLineHeight: token.controlHeight,
  239. customIconSize: token.controlHeight,
  240. customIconTop: 0,
  241. customIconFontSize: token.controlHeightSM,
  242. iconSize: token.controlHeight,
  243. iconTop: -0.5,
  244. // magic for ui experience
  245. iconFontSize: token.fontSize,
  246. iconSizeSM: token.fontSizeHeading3,
  247. dotSize: token.controlHeight / 4,
  248. dotCurrentSize: token.controlHeightLG / 4,
  249. navArrowColor: token.colorTextDisabled,
  250. navContentMaxWidth: 'unset',
  251. descriptionMaxWidth: 140,
  252. waitIconColor: token.wireframe ? token.colorTextDisabled : token.colorTextLabel,
  253. waitIconBgColor: token.wireframe ? token.colorBgContainer : token.colorFillContent,
  254. waitIconBorderColor: token.wireframe ? token.colorTextDisabled : 'transparent',
  255. finishIconBgColor: token.wireframe ? token.colorBgContainer : token.controlItemBgActive,
  256. finishIconBorderColor: token.wireframe ? token.colorPrimary : token.controlItemBgActive
  257. });
  258. export default genStyleHooks('Steps', token => {
  259. const {
  260. colorTextDisabled,
  261. controlHeightLG,
  262. colorTextLightSolid,
  263. colorText,
  264. colorPrimary,
  265. colorTextDescription,
  266. colorTextQuaternary,
  267. colorError,
  268. colorBorderSecondary,
  269. colorSplit
  270. } = token;
  271. const stepsToken = mergeToken(token, {
  272. // Steps component less variable
  273. processIconColor: colorTextLightSolid,
  274. processTitleColor: colorText,
  275. processDescriptionColor: colorText,
  276. processIconBgColor: colorPrimary,
  277. processIconBorderColor: colorPrimary,
  278. processDotColor: colorPrimary,
  279. processTailColor: colorSplit,
  280. waitTitleColor: colorTextDescription,
  281. waitDescriptionColor: colorTextDescription,
  282. waitTailColor: colorSplit,
  283. waitDotColor: colorTextDisabled,
  284. finishIconColor: colorPrimary,
  285. finishTitleColor: colorText,
  286. finishDescriptionColor: colorTextDescription,
  287. finishTailColor: colorPrimary,
  288. finishDotColor: colorPrimary,
  289. errorIconColor: colorTextLightSolid,
  290. errorTitleColor: colorError,
  291. errorDescriptionColor: colorError,
  292. errorTailColor: colorSplit,
  293. errorIconBgColor: colorError,
  294. errorIconBorderColor: colorError,
  295. errorDotColor: colorError,
  296. stepsNavActiveColor: colorPrimary,
  297. stepsProgressSize: controlHeightLG,
  298. // Steps inline variable
  299. inlineDotSize: 6,
  300. inlineTitleColor: colorTextQuaternary,
  301. inlineTailColor: colorBorderSecondary
  302. });
  303. return genStepsStyle(stepsToken);
  304. }, prepareComponentToken);