index.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. import _extends from "@babel/runtime/helpers/esm/extends";
  2. import { Keyframes } from '../../_util/cssinjs';
  3. import { genComponentStyleHook, mergeToken } from '../../theme/internal';
  4. import { genPresetColor, resetComponent } from '../../style';
  5. const antStatusProcessing = new Keyframes('antStatusProcessing', {
  6. '0%': {
  7. transform: 'scale(0.8)',
  8. opacity: 0.5
  9. },
  10. '100%': {
  11. transform: 'scale(2.4)',
  12. opacity: 0
  13. }
  14. });
  15. const antZoomBadgeIn = new Keyframes('antZoomBadgeIn', {
  16. '0%': {
  17. transform: 'scale(0) translate(50%, -50%)',
  18. opacity: 0
  19. },
  20. '100%': {
  21. transform: 'scale(1) translate(50%, -50%)'
  22. }
  23. });
  24. const antZoomBadgeOut = new Keyframes('antZoomBadgeOut', {
  25. '0%': {
  26. transform: 'scale(1) translate(50%, -50%)'
  27. },
  28. '100%': {
  29. transform: 'scale(0) translate(50%, -50%)',
  30. opacity: 0
  31. }
  32. });
  33. const antNoWrapperZoomBadgeIn = new Keyframes('antNoWrapperZoomBadgeIn', {
  34. '0%': {
  35. transform: 'scale(0)',
  36. opacity: 0
  37. },
  38. '100%': {
  39. transform: 'scale(1)'
  40. }
  41. });
  42. const antNoWrapperZoomBadgeOut = new Keyframes('antNoWrapperZoomBadgeOut', {
  43. '0%': {
  44. transform: 'scale(1)'
  45. },
  46. '100%': {
  47. transform: 'scale(0)',
  48. opacity: 0
  49. }
  50. });
  51. const antBadgeLoadingCircle = new Keyframes('antBadgeLoadingCircle', {
  52. '0%': {
  53. transformOrigin: '50%'
  54. },
  55. '100%': {
  56. transform: 'translate(50%, -50%) rotate(360deg)',
  57. transformOrigin: '50%'
  58. }
  59. });
  60. const genSharedBadgeStyle = token => {
  61. const {
  62. componentCls,
  63. iconCls,
  64. antCls,
  65. badgeFontHeight,
  66. badgeShadowSize,
  67. badgeHeightSm,
  68. motionDurationSlow,
  69. badgeStatusSize,
  70. marginXS,
  71. badgeRibbonOffset
  72. } = token;
  73. const numberPrefixCls = `${antCls}-scroll-number`;
  74. const ribbonPrefixCls = `${antCls}-ribbon`;
  75. const ribbonWrapperPrefixCls = `${antCls}-ribbon-wrapper`;
  76. const colorPreset = genPresetColor(token, (colorKey, _ref) => {
  77. let {
  78. darkColor
  79. } = _ref;
  80. return {
  81. [`&${componentCls} ${componentCls}-color-${colorKey}`]: {
  82. background: darkColor,
  83. [`&:not(${componentCls}-count)`]: {
  84. color: darkColor
  85. }
  86. }
  87. };
  88. });
  89. const statusRibbonPreset = genPresetColor(token, (colorKey, _ref2) => {
  90. let {
  91. darkColor
  92. } = _ref2;
  93. return {
  94. [`&${ribbonPrefixCls}-color-${colorKey}`]: {
  95. background: darkColor,
  96. color: darkColor
  97. }
  98. };
  99. });
  100. return {
  101. [componentCls]: _extends(_extends(_extends(_extends({}, resetComponent(token)), {
  102. position: 'relative',
  103. display: 'inline-block',
  104. width: 'fit-content',
  105. lineHeight: 1,
  106. [`${componentCls}-count`]: {
  107. zIndex: token.badgeZIndex,
  108. minWidth: token.badgeHeight,
  109. height: token.badgeHeight,
  110. color: token.badgeTextColor,
  111. fontWeight: token.badgeFontWeight,
  112. fontSize: token.badgeFontSize,
  113. lineHeight: `${token.badgeHeight}px`,
  114. whiteSpace: 'nowrap',
  115. textAlign: 'center',
  116. background: token.badgeColor,
  117. borderRadius: token.badgeHeight / 2,
  118. boxShadow: `0 0 0 ${badgeShadowSize}px ${token.badgeShadowColor}`,
  119. transition: `background ${token.motionDurationMid}`,
  120. a: {
  121. color: token.badgeTextColor
  122. },
  123. 'a:hover': {
  124. color: token.badgeTextColor
  125. },
  126. 'a:hover &': {
  127. background: token.badgeColorHover
  128. }
  129. },
  130. [`${componentCls}-count-sm`]: {
  131. minWidth: badgeHeightSm,
  132. height: badgeHeightSm,
  133. fontSize: token.badgeFontSizeSm,
  134. lineHeight: `${badgeHeightSm}px`,
  135. borderRadius: badgeHeightSm / 2
  136. },
  137. [`${componentCls}-multiple-words`]: {
  138. padding: `0 ${token.paddingXS}px`
  139. },
  140. [`${componentCls}-dot`]: {
  141. zIndex: token.badgeZIndex,
  142. width: token.badgeDotSize,
  143. minWidth: token.badgeDotSize,
  144. height: token.badgeDotSize,
  145. background: token.badgeColor,
  146. borderRadius: '100%',
  147. boxShadow: `0 0 0 ${badgeShadowSize}px ${token.badgeShadowColor}`
  148. },
  149. [`${componentCls}-dot${numberPrefixCls}`]: {
  150. transition: `background ${motionDurationSlow}`
  151. },
  152. [`${componentCls}-count, ${componentCls}-dot, ${numberPrefixCls}-custom-component`]: {
  153. position: 'absolute',
  154. top: 0,
  155. insetInlineEnd: 0,
  156. transform: 'translate(50%, -50%)',
  157. transformOrigin: '100% 0%',
  158. [`&${iconCls}-spin`]: {
  159. animationName: antBadgeLoadingCircle,
  160. animationDuration: '1s',
  161. animationIterationCount: 'infinite',
  162. animationTimingFunction: 'linear'
  163. }
  164. },
  165. [`&${componentCls}-status`]: {
  166. lineHeight: 'inherit',
  167. verticalAlign: 'baseline',
  168. [`${componentCls}-status-dot`]: {
  169. position: 'relative',
  170. top: -1,
  171. display: 'inline-block',
  172. width: badgeStatusSize,
  173. height: badgeStatusSize,
  174. verticalAlign: 'middle',
  175. borderRadius: '50%'
  176. },
  177. [`${componentCls}-status-success`]: {
  178. backgroundColor: token.colorSuccess
  179. },
  180. [`${componentCls}-status-processing`]: {
  181. overflow: 'visible',
  182. color: token.colorPrimary,
  183. backgroundColor: token.colorPrimary,
  184. '&::after': {
  185. position: 'absolute',
  186. top: 0,
  187. insetInlineStart: 0,
  188. width: '100%',
  189. height: '100%',
  190. borderWidth: badgeShadowSize,
  191. borderStyle: 'solid',
  192. borderColor: 'inherit',
  193. borderRadius: '50%',
  194. animationName: antStatusProcessing,
  195. animationDuration: token.badgeProcessingDuration,
  196. animationIterationCount: 'infinite',
  197. animationTimingFunction: 'ease-in-out',
  198. content: '""'
  199. }
  200. },
  201. [`${componentCls}-status-default`]: {
  202. backgroundColor: token.colorTextPlaceholder
  203. },
  204. [`${componentCls}-status-error`]: {
  205. backgroundColor: token.colorError
  206. },
  207. [`${componentCls}-status-warning`]: {
  208. backgroundColor: token.colorWarning
  209. },
  210. [`${componentCls}-status-text`]: {
  211. marginInlineStart: marginXS,
  212. color: token.colorText,
  213. fontSize: token.fontSize
  214. }
  215. }
  216. }), colorPreset), {
  217. [`${componentCls}-zoom-appear, ${componentCls}-zoom-enter`]: {
  218. animationName: antZoomBadgeIn,
  219. animationDuration: token.motionDurationSlow,
  220. animationTimingFunction: token.motionEaseOutBack,
  221. animationFillMode: 'both'
  222. },
  223. [`${componentCls}-zoom-leave`]: {
  224. animationName: antZoomBadgeOut,
  225. animationDuration: token.motionDurationSlow,
  226. animationTimingFunction: token.motionEaseOutBack,
  227. animationFillMode: 'both'
  228. },
  229. [`&${componentCls}-not-a-wrapper`]: {
  230. [`${componentCls}-zoom-appear, ${componentCls}-zoom-enter`]: {
  231. animationName: antNoWrapperZoomBadgeIn,
  232. animationDuration: token.motionDurationSlow,
  233. animationTimingFunction: token.motionEaseOutBack
  234. },
  235. [`${componentCls}-zoom-leave`]: {
  236. animationName: antNoWrapperZoomBadgeOut,
  237. animationDuration: token.motionDurationSlow,
  238. animationTimingFunction: token.motionEaseOutBack
  239. },
  240. [`&:not(${componentCls}-status)`]: {
  241. verticalAlign: 'middle'
  242. },
  243. [`${numberPrefixCls}-custom-component, ${componentCls}-count`]: {
  244. transform: 'none'
  245. },
  246. [`${numberPrefixCls}-custom-component, ${numberPrefixCls}`]: {
  247. position: 'relative',
  248. top: 'auto',
  249. display: 'block',
  250. transformOrigin: '50% 50%'
  251. }
  252. },
  253. [`${numberPrefixCls}`]: {
  254. overflow: 'hidden',
  255. [`${numberPrefixCls}-only`]: {
  256. position: 'relative',
  257. display: 'inline-block',
  258. height: token.badgeHeight,
  259. transition: `all ${token.motionDurationSlow} ${token.motionEaseOutBack}`,
  260. WebkitTransformStyle: 'preserve-3d',
  261. WebkitBackfaceVisibility: 'hidden',
  262. [`> p${numberPrefixCls}-only-unit`]: {
  263. height: token.badgeHeight,
  264. margin: 0,
  265. WebkitTransformStyle: 'preserve-3d',
  266. WebkitBackfaceVisibility: 'hidden'
  267. }
  268. },
  269. [`${numberPrefixCls}-symbol`]: {
  270. verticalAlign: 'top'
  271. }
  272. },
  273. // ====================== RTL =======================
  274. '&-rtl': {
  275. direction: 'rtl',
  276. [`${componentCls}-count, ${componentCls}-dot, ${numberPrefixCls}-custom-component`]: {
  277. transform: 'translate(-50%, -50%)'
  278. }
  279. }
  280. }),
  281. [`${ribbonWrapperPrefixCls}`]: {
  282. position: 'relative'
  283. },
  284. [`${ribbonPrefixCls}`]: _extends(_extends(_extends(_extends({}, resetComponent(token)), {
  285. position: 'absolute',
  286. top: marginXS,
  287. padding: `0 ${token.paddingXS}px`,
  288. color: token.colorPrimary,
  289. lineHeight: `${badgeFontHeight}px`,
  290. whiteSpace: 'nowrap',
  291. backgroundColor: token.colorPrimary,
  292. borderRadius: token.borderRadiusSM,
  293. [`${ribbonPrefixCls}-text`]: {
  294. color: token.colorTextLightSolid
  295. },
  296. [`${ribbonPrefixCls}-corner`]: {
  297. position: 'absolute',
  298. top: '100%',
  299. width: badgeRibbonOffset,
  300. height: badgeRibbonOffset,
  301. color: 'currentcolor',
  302. border: `${badgeRibbonOffset / 2}px solid`,
  303. transform: token.badgeRibbonCornerTransform,
  304. transformOrigin: 'top',
  305. filter: token.badgeRibbonCornerFilter
  306. }
  307. }), statusRibbonPreset), {
  308. [`&${ribbonPrefixCls}-placement-end`]: {
  309. insetInlineEnd: -badgeRibbonOffset,
  310. borderEndEndRadius: 0,
  311. [`${ribbonPrefixCls}-corner`]: {
  312. insetInlineEnd: 0,
  313. borderInlineEndColor: 'transparent',
  314. borderBlockEndColor: 'transparent'
  315. }
  316. },
  317. [`&${ribbonPrefixCls}-placement-start`]: {
  318. insetInlineStart: -badgeRibbonOffset,
  319. borderEndStartRadius: 0,
  320. [`${ribbonPrefixCls}-corner`]: {
  321. insetInlineStart: 0,
  322. borderBlockEndColor: 'transparent',
  323. borderInlineStartColor: 'transparent'
  324. }
  325. },
  326. // ====================== RTL =======================
  327. '&-rtl': {
  328. direction: 'rtl'
  329. }
  330. })
  331. };
  332. };
  333. // ============================== Export ==============================
  334. export default genComponentStyleHook('Badge', token => {
  335. const {
  336. fontSize,
  337. lineHeight,
  338. fontSizeSM,
  339. lineWidth,
  340. marginXS,
  341. colorBorderBg
  342. } = token;
  343. const badgeFontHeight = Math.round(fontSize * lineHeight);
  344. const badgeShadowSize = lineWidth;
  345. const badgeZIndex = 'auto';
  346. const badgeHeight = badgeFontHeight - 2 * badgeShadowSize;
  347. const badgeTextColor = token.colorBgContainer;
  348. const badgeFontWeight = 'normal';
  349. const badgeFontSize = fontSizeSM;
  350. const badgeColor = token.colorError;
  351. const badgeColorHover = token.colorErrorHover;
  352. const badgeHeightSm = fontSize;
  353. const badgeDotSize = fontSizeSM / 2;
  354. const badgeFontSizeSm = fontSizeSM;
  355. const badgeStatusSize = fontSizeSM / 2;
  356. const badgeToken = mergeToken(token, {
  357. badgeFontHeight,
  358. badgeShadowSize,
  359. badgeZIndex,
  360. badgeHeight,
  361. badgeTextColor,
  362. badgeFontWeight,
  363. badgeFontSize,
  364. badgeColor,
  365. badgeColorHover,
  366. badgeShadowColor: colorBorderBg,
  367. badgeHeightSm,
  368. badgeDotSize,
  369. badgeFontSizeSm,
  370. badgeStatusSize,
  371. badgeProcessingDuration: '1.2s',
  372. badgeRibbonOffset: marginXS,
  373. // Follow token just by Design. Not related with token
  374. badgeRibbonCornerTransform: 'scaleY(0.75)',
  375. badgeRibbonCornerFilter: `brightness(75%)`
  376. });
  377. return [genSharedBadgeStyle(badgeToken)];
  378. });