index.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. import { unit } from '@ant-design/cssinjs';
  2. import { clearFix, resetComponent, textEllipsis } from '../../style';
  3. import { genStyleHooks, mergeToken } from '../../theme/internal';
  4. // ============================== Styles ==============================
  5. // ============================== Head ==============================
  6. const genCardHeadStyle = token => {
  7. const {
  8. antCls,
  9. componentCls,
  10. headerHeight,
  11. headerPadding,
  12. tabsMarginBottom
  13. } = token;
  14. return Object.assign(Object.assign({
  15. display: 'flex',
  16. justifyContent: 'center',
  17. flexDirection: 'column',
  18. minHeight: headerHeight,
  19. marginBottom: -1,
  20. padding: `0 ${unit(headerPadding)}`,
  21. color: token.colorTextHeading,
  22. fontWeight: token.fontWeightStrong,
  23. fontSize: token.headerFontSize,
  24. background: token.headerBg,
  25. borderBottom: `${unit(token.lineWidth)} ${token.lineType} ${token.colorBorderSecondary}`,
  26. borderRadius: `${unit(token.borderRadiusLG)} ${unit(token.borderRadiusLG)} 0 0`
  27. }, clearFix()), {
  28. '&-wrapper': {
  29. width: '100%',
  30. display: 'flex',
  31. alignItems: 'center'
  32. },
  33. '&-title': Object.assign(Object.assign({
  34. display: 'inline-block',
  35. flex: 1
  36. }, textEllipsis), {
  37. [`
  38. > ${componentCls}-typography,
  39. > ${componentCls}-typography-edit-content
  40. `]: {
  41. insetInlineStart: 0,
  42. marginTop: 0,
  43. marginBottom: 0
  44. }
  45. }),
  46. [`${antCls}-tabs-top`]: {
  47. clear: 'both',
  48. marginBottom: tabsMarginBottom,
  49. color: token.colorText,
  50. fontWeight: 'normal',
  51. fontSize: token.fontSize,
  52. '&-bar': {
  53. borderBottom: `${unit(token.lineWidth)} ${token.lineType} ${token.colorBorderSecondary}`
  54. }
  55. }
  56. });
  57. };
  58. // ============================== Grid ==============================
  59. const genCardGridStyle = token => {
  60. const {
  61. cardPaddingBase,
  62. colorBorderSecondary,
  63. cardShadow,
  64. lineWidth
  65. } = token;
  66. return {
  67. width: '33.33%',
  68. padding: cardPaddingBase,
  69. border: 0,
  70. borderRadius: 0,
  71. boxShadow: `
  72. ${unit(lineWidth)} 0 0 0 ${colorBorderSecondary},
  73. 0 ${unit(lineWidth)} 0 0 ${colorBorderSecondary},
  74. ${unit(lineWidth)} ${unit(lineWidth)} 0 0 ${colorBorderSecondary},
  75. ${unit(lineWidth)} 0 0 0 ${colorBorderSecondary} inset,
  76. 0 ${unit(lineWidth)} 0 0 ${colorBorderSecondary} inset;
  77. `,
  78. transition: `all ${token.motionDurationMid}`,
  79. '&-hoverable:hover': {
  80. position: 'relative',
  81. zIndex: 1,
  82. boxShadow: cardShadow
  83. }
  84. };
  85. };
  86. // ============================== Actions ==============================
  87. const genCardActionsStyle = token => {
  88. const {
  89. componentCls,
  90. iconCls,
  91. actionsLiMargin,
  92. cardActionsIconSize,
  93. colorBorderSecondary,
  94. actionsBg
  95. } = token;
  96. return Object.assign(Object.assign({
  97. margin: 0,
  98. padding: 0,
  99. listStyle: 'none',
  100. background: actionsBg,
  101. borderTop: `${unit(token.lineWidth)} ${token.lineType} ${colorBorderSecondary}`,
  102. display: 'flex',
  103. borderRadius: `0 0 ${unit(token.borderRadiusLG)} ${unit(token.borderRadiusLG)}`
  104. }, clearFix()), {
  105. '& > li': {
  106. margin: actionsLiMargin,
  107. color: token.colorTextDescription,
  108. textAlign: 'center',
  109. '> span': {
  110. position: 'relative',
  111. display: 'block',
  112. minWidth: token.calc(token.cardActionsIconSize).mul(2).equal(),
  113. fontSize: token.fontSize,
  114. lineHeight: token.lineHeight,
  115. cursor: 'pointer',
  116. '&:hover': {
  117. color: token.colorPrimary,
  118. transition: `color ${token.motionDurationMid}`
  119. },
  120. [`a:not(${componentCls}-btn), > ${iconCls}`]: {
  121. display: 'inline-block',
  122. width: '100%',
  123. color: token.colorIcon,
  124. lineHeight: unit(token.fontHeight),
  125. transition: `color ${token.motionDurationMid}`,
  126. '&:hover': {
  127. color: token.colorPrimary
  128. }
  129. },
  130. [`> ${iconCls}`]: {
  131. fontSize: cardActionsIconSize,
  132. lineHeight: unit(token.calc(cardActionsIconSize).mul(token.lineHeight).equal())
  133. }
  134. },
  135. '&:not(:last-child)': {
  136. borderInlineEnd: `${unit(token.lineWidth)} ${token.lineType} ${colorBorderSecondary}`
  137. }
  138. }
  139. });
  140. };
  141. // ============================== Meta ==============================
  142. const genCardMetaStyle = token => Object.assign(Object.assign({
  143. margin: `${unit(token.calc(token.marginXXS).mul(-1).equal())} 0`,
  144. display: 'flex'
  145. }, clearFix()), {
  146. '&-avatar': {
  147. paddingInlineEnd: token.padding
  148. },
  149. '&-detail': {
  150. overflow: 'hidden',
  151. flex: 1,
  152. '> div:not(:last-child)': {
  153. marginBottom: token.marginXS
  154. }
  155. },
  156. '&-title': Object.assign({
  157. color: token.colorTextHeading,
  158. fontWeight: token.fontWeightStrong,
  159. fontSize: token.fontSizeLG
  160. }, textEllipsis),
  161. '&-description': {
  162. color: token.colorTextDescription
  163. }
  164. });
  165. // ============================== Inner ==============================
  166. const genCardTypeInnerStyle = token => {
  167. const {
  168. componentCls,
  169. colorFillAlter,
  170. headerPadding,
  171. bodyPadding
  172. } = token;
  173. return {
  174. [`${componentCls}-head`]: {
  175. padding: `0 ${unit(headerPadding)}`,
  176. background: colorFillAlter,
  177. '&-title': {
  178. fontSize: token.fontSize
  179. }
  180. },
  181. [`${componentCls}-body`]: {
  182. padding: `${unit(token.padding)} ${unit(bodyPadding)}`
  183. }
  184. };
  185. };
  186. // ============================== Loading ==============================
  187. const genCardLoadingStyle = token => {
  188. const {
  189. componentCls
  190. } = token;
  191. return {
  192. overflow: 'hidden',
  193. [`${componentCls}-body`]: {
  194. userSelect: 'none'
  195. }
  196. };
  197. };
  198. // ============================== Basic ==============================
  199. const genCardStyle = token => {
  200. const {
  201. componentCls,
  202. cardShadow,
  203. cardHeadPadding,
  204. colorBorderSecondary,
  205. boxShadowTertiary,
  206. bodyPadding,
  207. extraColor
  208. } = token;
  209. return {
  210. [componentCls]: Object.assign(Object.assign({}, resetComponent(token)), {
  211. position: 'relative',
  212. background: token.colorBgContainer,
  213. borderRadius: token.borderRadiusLG,
  214. [`&:not(${componentCls}-bordered)`]: {
  215. boxShadow: boxShadowTertiary
  216. },
  217. [`${componentCls}-head`]: genCardHeadStyle(token),
  218. [`${componentCls}-extra`]: {
  219. // https://stackoverflow.com/a/22429853/3040605
  220. marginInlineStart: 'auto',
  221. color: extraColor,
  222. fontWeight: 'normal',
  223. fontSize: token.fontSize
  224. },
  225. [`${componentCls}-body`]: Object.assign({
  226. padding: bodyPadding,
  227. borderRadius: `0 0 ${unit(token.borderRadiusLG)} ${unit(token.borderRadiusLG)}`
  228. }, clearFix()),
  229. [`${componentCls}-grid`]: genCardGridStyle(token),
  230. [`${componentCls}-cover`]: {
  231. '> *': {
  232. display: 'block',
  233. width: '100%',
  234. borderRadius: `${unit(token.borderRadiusLG)} ${unit(token.borderRadiusLG)} 0 0`
  235. }
  236. },
  237. [`${componentCls}-actions`]: genCardActionsStyle(token),
  238. [`${componentCls}-meta`]: genCardMetaStyle(token)
  239. }),
  240. [`${componentCls}-bordered`]: {
  241. border: `${unit(token.lineWidth)} ${token.lineType} ${colorBorderSecondary}`,
  242. [`${componentCls}-cover`]: {
  243. marginTop: -1,
  244. marginInlineStart: -1,
  245. marginInlineEnd: -1
  246. }
  247. },
  248. [`${componentCls}-hoverable`]: {
  249. cursor: 'pointer',
  250. transition: `box-shadow ${token.motionDurationMid}, border-color ${token.motionDurationMid}`,
  251. '&:hover': {
  252. borderColor: 'transparent',
  253. boxShadow: cardShadow
  254. }
  255. },
  256. [`${componentCls}-contain-grid`]: {
  257. borderRadius: `${unit(token.borderRadiusLG)} ${unit(token.borderRadiusLG)} 0 0 `,
  258. [`${componentCls}-body`]: {
  259. display: 'flex',
  260. flexWrap: 'wrap'
  261. },
  262. [`&:not(${componentCls}-loading) ${componentCls}-body`]: {
  263. marginBlockStart: token.calc(token.lineWidth).mul(-1).equal(),
  264. marginInlineStart: token.calc(token.lineWidth).mul(-1).equal(),
  265. padding: 0
  266. }
  267. },
  268. [`${componentCls}-contain-tabs`]: {
  269. [`> div${componentCls}-head`]: {
  270. minHeight: 0,
  271. [`${componentCls}-head-title, ${componentCls}-extra`]: {
  272. paddingTop: cardHeadPadding
  273. }
  274. }
  275. },
  276. [`${componentCls}-type-inner`]: genCardTypeInnerStyle(token),
  277. [`${componentCls}-loading`]: genCardLoadingStyle(token),
  278. [`${componentCls}-rtl`]: {
  279. direction: 'rtl'
  280. }
  281. };
  282. };
  283. // ============================== Size ==============================
  284. const genCardSizeStyle = token => {
  285. const {
  286. componentCls,
  287. bodyPaddingSM,
  288. headerPaddingSM,
  289. headerHeightSM,
  290. headerFontSizeSM
  291. } = token;
  292. return {
  293. [`${componentCls}-small`]: {
  294. [`> ${componentCls}-head`]: {
  295. minHeight: headerHeightSM,
  296. padding: `0 ${unit(headerPaddingSM)}`,
  297. fontSize: headerFontSizeSM,
  298. [`> ${componentCls}-head-wrapper`]: {
  299. [`> ${componentCls}-extra`]: {
  300. fontSize: token.fontSize
  301. }
  302. }
  303. },
  304. [`> ${componentCls}-body`]: {
  305. padding: bodyPaddingSM
  306. }
  307. },
  308. [`${componentCls}-small${componentCls}-contain-tabs`]: {
  309. [`> ${componentCls}-head`]: {
  310. [`${componentCls}-head-title, ${componentCls}-extra`]: {
  311. paddingTop: 0,
  312. display: 'flex',
  313. alignItems: 'center'
  314. }
  315. }
  316. }
  317. };
  318. };
  319. export const prepareComponentToken = token => {
  320. var _a, _b;
  321. return {
  322. headerBg: 'transparent',
  323. headerFontSize: token.fontSizeLG,
  324. headerFontSizeSM: token.fontSize,
  325. headerHeight: token.fontSizeLG * token.lineHeightLG + token.padding * 2,
  326. headerHeightSM: token.fontSize * token.lineHeight + token.paddingXS * 2,
  327. actionsBg: token.colorBgContainer,
  328. actionsLiMargin: `${token.paddingSM}px 0`,
  329. tabsMarginBottom: -token.padding - token.lineWidth,
  330. extraColor: token.colorText,
  331. bodyPaddingSM: 12,
  332. // Fixed padding.
  333. headerPaddingSM: 12,
  334. bodyPadding: (_a = token.bodyPadding) !== null && _a !== void 0 ? _a : token.paddingLG,
  335. headerPadding: (_b = token.headerPadding) !== null && _b !== void 0 ? _b : token.paddingLG
  336. };
  337. };
  338. // ============================== Export ==============================
  339. export default genStyleHooks('Card', token => {
  340. const cardToken = mergeToken(token, {
  341. cardShadow: token.boxShadowCard,
  342. cardHeadPadding: token.padding,
  343. cardPaddingBase: token.paddingLG,
  344. cardActionsIconSize: token.fontSize
  345. });
  346. return [
  347. // Style
  348. genCardStyle(cardToken),
  349. // Size
  350. genCardSizeStyle(cardToken)];
  351. }, prepareComponentToken);