index.js 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. import _extends from "@babel/runtime/helpers/esm/extends";
  2. import { Keyframes } from '../../_util/cssinjs';
  3. import { genComponentStyleHook, mergeToken } from '../../theme/internal';
  4. const skeletonClsLoading = new Keyframes(`ant-skeleton-loading`, {
  5. '0%': {
  6. transform: 'translateX(-37.5%)'
  7. },
  8. '100%': {
  9. transform: 'translateX(37.5%)'
  10. }
  11. });
  12. const genSkeletonElementCommonSize = size => ({
  13. height: size,
  14. lineHeight: `${size}px`
  15. });
  16. const genSkeletonElementAvatarSize = size => _extends({
  17. width: size
  18. }, genSkeletonElementCommonSize(size));
  19. const genSkeletonColor = token => ({
  20. position: 'relative',
  21. // fix https://github.com/ant-design/ant-design/issues/36444
  22. // https://monshin.github.io/202109/css/safari-border-radius-overflow-hidden/
  23. /* stylelint-disable-next-line property-no-vendor-prefix,value-no-vendor-prefix */
  24. zIndex: 0,
  25. overflow: 'hidden',
  26. background: 'transparent',
  27. '&::after': {
  28. position: 'absolute',
  29. top: 0,
  30. insetInlineEnd: '-150%',
  31. bottom: 0,
  32. insetInlineStart: '-150%',
  33. background: token.skeletonLoadingBackground,
  34. animationName: skeletonClsLoading,
  35. animationDuration: token.skeletonLoadingMotionDuration,
  36. animationTimingFunction: 'ease',
  37. animationIterationCount: 'infinite',
  38. content: '""'
  39. }
  40. });
  41. const genSkeletonElementInputSize = size => _extends({
  42. width: size * 5,
  43. minWidth: size * 5
  44. }, genSkeletonElementCommonSize(size));
  45. const genSkeletonElementAvatar = token => {
  46. const {
  47. skeletonAvatarCls,
  48. color,
  49. controlHeight,
  50. controlHeightLG,
  51. controlHeightSM
  52. } = token;
  53. return {
  54. [`${skeletonAvatarCls}`]: _extends({
  55. display: 'inline-block',
  56. verticalAlign: 'top',
  57. background: color
  58. }, genSkeletonElementAvatarSize(controlHeight)),
  59. [`${skeletonAvatarCls}${skeletonAvatarCls}-circle`]: {
  60. borderRadius: '50%'
  61. },
  62. [`${skeletonAvatarCls}${skeletonAvatarCls}-lg`]: _extends({}, genSkeletonElementAvatarSize(controlHeightLG)),
  63. [`${skeletonAvatarCls}${skeletonAvatarCls}-sm`]: _extends({}, genSkeletonElementAvatarSize(controlHeightSM))
  64. };
  65. };
  66. const genSkeletonElementInput = token => {
  67. const {
  68. controlHeight,
  69. borderRadiusSM,
  70. skeletonInputCls,
  71. controlHeightLG,
  72. controlHeightSM,
  73. color
  74. } = token;
  75. return {
  76. [`${skeletonInputCls}`]: _extends({
  77. display: 'inline-block',
  78. verticalAlign: 'top',
  79. background: color,
  80. borderRadius: borderRadiusSM
  81. }, genSkeletonElementInputSize(controlHeight)),
  82. [`${skeletonInputCls}-lg`]: _extends({}, genSkeletonElementInputSize(controlHeightLG)),
  83. [`${skeletonInputCls}-sm`]: _extends({}, genSkeletonElementInputSize(controlHeightSM))
  84. };
  85. };
  86. const genSkeletonElementImageSize = size => _extends({
  87. width: size
  88. }, genSkeletonElementCommonSize(size));
  89. const genSkeletonElementImage = token => {
  90. const {
  91. skeletonImageCls,
  92. imageSizeBase,
  93. color,
  94. borderRadiusSM
  95. } = token;
  96. return {
  97. [`${skeletonImageCls}`]: _extends(_extends({
  98. display: 'flex',
  99. alignItems: 'center',
  100. justifyContent: 'center',
  101. verticalAlign: 'top',
  102. background: color,
  103. borderRadius: borderRadiusSM
  104. }, genSkeletonElementImageSize(imageSizeBase * 2)), {
  105. [`${skeletonImageCls}-path`]: {
  106. fill: '#bfbfbf'
  107. },
  108. [`${skeletonImageCls}-svg`]: _extends(_extends({}, genSkeletonElementImageSize(imageSizeBase)), {
  109. maxWidth: imageSizeBase * 4,
  110. maxHeight: imageSizeBase * 4
  111. }),
  112. [`${skeletonImageCls}-svg${skeletonImageCls}-svg-circle`]: {
  113. borderRadius: '50%'
  114. }
  115. }),
  116. [`${skeletonImageCls}${skeletonImageCls}-circle`]: {
  117. borderRadius: '50%'
  118. }
  119. };
  120. };
  121. const genSkeletonElementButtonShape = (token, size, buttonCls) => {
  122. const {
  123. skeletonButtonCls
  124. } = token;
  125. return {
  126. [`${buttonCls}${skeletonButtonCls}-circle`]: {
  127. width: size,
  128. minWidth: size,
  129. borderRadius: '50%'
  130. },
  131. [`${buttonCls}${skeletonButtonCls}-round`]: {
  132. borderRadius: size
  133. }
  134. };
  135. };
  136. const genSkeletonElementButtonSize = size => _extends({
  137. width: size * 2,
  138. minWidth: size * 2
  139. }, genSkeletonElementCommonSize(size));
  140. const genSkeletonElementButton = token => {
  141. const {
  142. borderRadiusSM,
  143. skeletonButtonCls,
  144. controlHeight,
  145. controlHeightLG,
  146. controlHeightSM,
  147. color
  148. } = token;
  149. return _extends(_extends(_extends(_extends(_extends({
  150. [`${skeletonButtonCls}`]: _extends({
  151. display: 'inline-block',
  152. verticalAlign: 'top',
  153. background: color,
  154. borderRadius: borderRadiusSM,
  155. width: controlHeight * 2,
  156. minWidth: controlHeight * 2
  157. }, genSkeletonElementButtonSize(controlHeight))
  158. }, genSkeletonElementButtonShape(token, controlHeight, skeletonButtonCls)), {
  159. [`${skeletonButtonCls}-lg`]: _extends({}, genSkeletonElementButtonSize(controlHeightLG))
  160. }), genSkeletonElementButtonShape(token, controlHeightLG, `${skeletonButtonCls}-lg`)), {
  161. [`${skeletonButtonCls}-sm`]: _extends({}, genSkeletonElementButtonSize(controlHeightSM))
  162. }), genSkeletonElementButtonShape(token, controlHeightSM, `${skeletonButtonCls}-sm`));
  163. };
  164. // =============================== Base ===============================
  165. const genBaseStyle = token => {
  166. const {
  167. componentCls,
  168. skeletonAvatarCls,
  169. skeletonTitleCls,
  170. skeletonParagraphCls,
  171. skeletonButtonCls,
  172. skeletonInputCls,
  173. skeletonImageCls,
  174. controlHeight,
  175. controlHeightLG,
  176. controlHeightSM,
  177. color,
  178. padding,
  179. marginSM,
  180. borderRadius,
  181. skeletonTitleHeight,
  182. skeletonBlockRadius,
  183. skeletonParagraphLineHeight,
  184. controlHeightXS,
  185. skeletonParagraphMarginTop
  186. } = token;
  187. return {
  188. [`${componentCls}`]: {
  189. display: 'table',
  190. width: '100%',
  191. [`${componentCls}-header`]: {
  192. display: 'table-cell',
  193. paddingInlineEnd: padding,
  194. verticalAlign: 'top',
  195. // Avatar
  196. [`${skeletonAvatarCls}`]: _extends({
  197. display: 'inline-block',
  198. verticalAlign: 'top',
  199. background: color
  200. }, genSkeletonElementAvatarSize(controlHeight)),
  201. [`${skeletonAvatarCls}-circle`]: {
  202. borderRadius: '50%'
  203. },
  204. [`${skeletonAvatarCls}-lg`]: _extends({}, genSkeletonElementAvatarSize(controlHeightLG)),
  205. [`${skeletonAvatarCls}-sm`]: _extends({}, genSkeletonElementAvatarSize(controlHeightSM))
  206. },
  207. [`${componentCls}-content`]: {
  208. display: 'table-cell',
  209. width: '100%',
  210. verticalAlign: 'top',
  211. // Title
  212. [`${skeletonTitleCls}`]: {
  213. width: '100%',
  214. height: skeletonTitleHeight,
  215. background: color,
  216. borderRadius: skeletonBlockRadius,
  217. [`+ ${skeletonParagraphCls}`]: {
  218. marginBlockStart: controlHeightSM
  219. }
  220. },
  221. // paragraph
  222. [`${skeletonParagraphCls}`]: {
  223. padding: 0,
  224. '> li': {
  225. width: '100%',
  226. height: skeletonParagraphLineHeight,
  227. listStyle: 'none',
  228. background: color,
  229. borderRadius: skeletonBlockRadius,
  230. '+ li': {
  231. marginBlockStart: controlHeightXS
  232. }
  233. }
  234. },
  235. [`${skeletonParagraphCls}> li:last-child:not(:first-child):not(:nth-child(2))`]: {
  236. width: '61%'
  237. }
  238. },
  239. [`&-round ${componentCls}-content`]: {
  240. [`${skeletonTitleCls}, ${skeletonParagraphCls} > li`]: {
  241. borderRadius
  242. }
  243. }
  244. },
  245. [`${componentCls}-with-avatar ${componentCls}-content`]: {
  246. // Title
  247. [`${skeletonTitleCls}`]: {
  248. marginBlockStart: marginSM,
  249. [`+ ${skeletonParagraphCls}`]: {
  250. marginBlockStart: skeletonParagraphMarginTop
  251. }
  252. }
  253. },
  254. // Skeleton element
  255. [`${componentCls}${componentCls}-element`]: _extends(_extends(_extends(_extends({
  256. display: 'inline-block',
  257. width: 'auto'
  258. }, genSkeletonElementButton(token)), genSkeletonElementAvatar(token)), genSkeletonElementInput(token)), genSkeletonElementImage(token)),
  259. // Skeleton Block Button, Input
  260. [`${componentCls}${componentCls}-block`]: {
  261. width: '100%',
  262. [`${skeletonButtonCls}`]: {
  263. width: '100%'
  264. },
  265. [`${skeletonInputCls}`]: {
  266. width: '100%'
  267. }
  268. },
  269. // With active animation
  270. [`${componentCls}${componentCls}-active`]: {
  271. [`
  272. ${skeletonTitleCls},
  273. ${skeletonParagraphCls} > li,
  274. ${skeletonAvatarCls},
  275. ${skeletonButtonCls},
  276. ${skeletonInputCls},
  277. ${skeletonImageCls}
  278. `]: _extends({}, genSkeletonColor(token))
  279. }
  280. };
  281. };
  282. // ============================== Export ==============================
  283. export default genComponentStyleHook('Skeleton', token => {
  284. const {
  285. componentCls
  286. } = token;
  287. const skeletonToken = mergeToken(token, {
  288. skeletonAvatarCls: `${componentCls}-avatar`,
  289. skeletonTitleCls: `${componentCls}-title`,
  290. skeletonParagraphCls: `${componentCls}-paragraph`,
  291. skeletonButtonCls: `${componentCls}-button`,
  292. skeletonInputCls: `${componentCls}-input`,
  293. skeletonImageCls: `${componentCls}-image`,
  294. imageSizeBase: token.controlHeight * 1.5,
  295. skeletonTitleHeight: token.controlHeight / 2,
  296. skeletonBlockRadius: token.borderRadiusSM,
  297. skeletonParagraphLineHeight: token.controlHeight / 2,
  298. skeletonParagraphMarginTop: token.marginLG + token.marginXXS,
  299. borderRadius: 100,
  300. skeletonLoadingBackground: `linear-gradient(90deg, ${token.color} 25%, ${token.colorGradientEnd} 37%, ${token.color} 63%)`,
  301. skeletonLoadingMotionDuration: '1.4s'
  302. });
  303. return [genBaseStyle(skeletonToken)];
  304. }, token => {
  305. const {
  306. colorFillContent,
  307. colorFill
  308. } = token;
  309. return {
  310. color: colorFillContent,
  311. colorGradientEnd: colorFill
  312. };
  313. });