index.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
  2. import { unit } from '@ant-design/cssinjs';
  3. import { getMediaSize } from '../../grid/style';
  4. import { genFocusStyle, resetComponent } from '../../style';
  5. import { initFadeMotion, initZoomMotion } from '../../style/motion';
  6. import { genStyleHooks, mergeToken } from '../../theme/internal';
  7. function box(position) {
  8. return {
  9. position,
  10. inset: 0
  11. };
  12. }
  13. export const genModalMaskStyle = token => {
  14. const {
  15. componentCls,
  16. antCls
  17. } = token;
  18. return [{
  19. [`${componentCls}-root`]: {
  20. [`${componentCls}${antCls}-zoom-enter, ${componentCls}${antCls}-zoom-appear`]: {
  21. // reset scale avoid mousePosition bug
  22. transform: 'none',
  23. opacity: 0,
  24. animationDuration: token.motionDurationSlow,
  25. // https://github.com/ant-design/ant-design/issues/11777
  26. userSelect: 'none'
  27. },
  28. // https://github.com/ant-design/ant-design/issues/37329
  29. // https://github.com/ant-design/ant-design/issues/40272
  30. [`${componentCls}${antCls}-zoom-leave ${componentCls}-content`]: {
  31. pointerEvents: 'none'
  32. },
  33. [`${componentCls}-mask`]: Object.assign(Object.assign({}, box('fixed')), {
  34. zIndex: token.zIndexPopupBase,
  35. height: '100%',
  36. backgroundColor: token.colorBgMask,
  37. pointerEvents: 'none',
  38. [`${componentCls}-hidden`]: {
  39. display: 'none'
  40. }
  41. }),
  42. [`${componentCls}-wrap`]: Object.assign(Object.assign({}, box('fixed')), {
  43. zIndex: token.zIndexPopupBase,
  44. overflow: 'auto',
  45. outline: 0,
  46. WebkitOverflowScrolling: 'touch'
  47. })
  48. }
  49. }, {
  50. [`${componentCls}-root`]: initFadeMotion(token)
  51. }];
  52. };
  53. const genModalStyle = token => {
  54. const {
  55. componentCls
  56. } = token;
  57. return [
  58. // ======================== Root =========================
  59. {
  60. [`${componentCls}-root`]: {
  61. [`${componentCls}-wrap-rtl`]: {
  62. direction: 'rtl'
  63. },
  64. [`${componentCls}-centered`]: {
  65. textAlign: 'center',
  66. '&::before': {
  67. display: 'inline-block',
  68. width: 0,
  69. height: '100%',
  70. verticalAlign: 'middle',
  71. content: '""'
  72. },
  73. [componentCls]: {
  74. top: 0,
  75. display: 'inline-block',
  76. paddingBottom: 0,
  77. textAlign: 'start',
  78. verticalAlign: 'middle'
  79. }
  80. },
  81. [`@media (max-width: ${token.screenSMMax}px)`]: {
  82. [componentCls]: {
  83. maxWidth: 'calc(100vw - 16px)',
  84. margin: `${unit(token.marginXS)} auto`
  85. },
  86. [`${componentCls}-centered`]: {
  87. [componentCls]: {
  88. flex: 1
  89. }
  90. }
  91. }
  92. }
  93. },
  94. // ======================== Modal ========================
  95. {
  96. [componentCls]: Object.assign(Object.assign({}, resetComponent(token)), {
  97. pointerEvents: 'none',
  98. position: 'relative',
  99. top: 100,
  100. width: 'auto',
  101. maxWidth: `calc(100vw - ${unit(token.calc(token.margin).mul(2).equal())})`,
  102. margin: '0 auto',
  103. paddingBottom: token.paddingLG,
  104. [`${componentCls}-title`]: {
  105. margin: 0,
  106. color: token.titleColor,
  107. fontWeight: token.fontWeightStrong,
  108. fontSize: token.titleFontSize,
  109. lineHeight: token.titleLineHeight,
  110. wordWrap: 'break-word'
  111. },
  112. [`${componentCls}-content`]: {
  113. position: 'relative',
  114. backgroundColor: token.contentBg,
  115. backgroundClip: 'padding-box',
  116. border: 0,
  117. borderRadius: token.borderRadiusLG,
  118. boxShadow: token.boxShadow,
  119. pointerEvents: 'auto',
  120. padding: token.contentPadding
  121. },
  122. [`${componentCls}-close`]: Object.assign({
  123. position: 'absolute',
  124. top: token.calc(token.modalHeaderHeight).sub(token.modalCloseBtnSize).div(2).equal(),
  125. insetInlineEnd: token.calc(token.modalHeaderHeight).sub(token.modalCloseBtnSize).div(2).equal(),
  126. zIndex: token.calc(token.zIndexPopupBase).add(10).equal(),
  127. padding: 0,
  128. color: token.modalCloseIconColor,
  129. fontWeight: token.fontWeightStrong,
  130. lineHeight: 1,
  131. textDecoration: 'none',
  132. background: 'transparent',
  133. borderRadius: token.borderRadiusSM,
  134. width: token.modalCloseBtnSize,
  135. height: token.modalCloseBtnSize,
  136. border: 0,
  137. outline: 0,
  138. cursor: 'pointer',
  139. transition: `color ${token.motionDurationMid}, background-color ${token.motionDurationMid}`,
  140. '&-x': {
  141. display: 'flex',
  142. fontSize: token.fontSizeLG,
  143. fontStyle: 'normal',
  144. lineHeight: unit(token.modalCloseBtnSize),
  145. justifyContent: 'center',
  146. textTransform: 'none',
  147. textRendering: 'auto'
  148. },
  149. '&:disabled': {
  150. pointerEvents: 'none'
  151. },
  152. '&:hover': {
  153. color: token.modalCloseIconHoverColor,
  154. backgroundColor: token.colorBgTextHover,
  155. textDecoration: 'none'
  156. },
  157. '&:active': {
  158. backgroundColor: token.colorBgTextActive
  159. }
  160. }, genFocusStyle(token)),
  161. [`${componentCls}-header`]: {
  162. color: token.colorText,
  163. background: token.headerBg,
  164. borderRadius: `${unit(token.borderRadiusLG)} ${unit(token.borderRadiusLG)} 0 0`,
  165. marginBottom: token.headerMarginBottom,
  166. padding: token.headerPadding,
  167. borderBottom: token.headerBorderBottom
  168. },
  169. [`${componentCls}-body`]: {
  170. fontSize: token.fontSize,
  171. lineHeight: token.lineHeight,
  172. wordWrap: 'break-word',
  173. padding: token.bodyPadding,
  174. [`${componentCls}-body-skeleton`]: {
  175. width: '100%',
  176. height: '100%',
  177. display: 'flex',
  178. justifyContent: 'center',
  179. alignItems: 'center',
  180. margin: `${unit(token.margin)} auto`
  181. }
  182. },
  183. [`${componentCls}-footer`]: {
  184. textAlign: 'end',
  185. background: token.footerBg,
  186. marginTop: token.footerMarginTop,
  187. padding: token.footerPadding,
  188. borderTop: token.footerBorderTop,
  189. borderRadius: token.footerBorderRadius,
  190. [`> ${token.antCls}-btn + ${token.antCls}-btn`]: {
  191. marginInlineStart: token.marginXS
  192. }
  193. },
  194. [`${componentCls}-open`]: {
  195. overflow: 'hidden'
  196. }
  197. })
  198. },
  199. // ======================== Pure =========================
  200. {
  201. [`${componentCls}-pure-panel`]: {
  202. top: 'auto',
  203. padding: 0,
  204. display: 'flex',
  205. flexDirection: 'column',
  206. [`${componentCls}-content,
  207. ${componentCls}-body,
  208. ${componentCls}-confirm-body-wrapper`]: {
  209. display: 'flex',
  210. flexDirection: 'column',
  211. flex: 'auto'
  212. },
  213. [`${componentCls}-confirm-body`]: {
  214. marginBottom: 'auto'
  215. }
  216. }
  217. }];
  218. };
  219. const genRTLStyle = token => {
  220. const {
  221. componentCls
  222. } = token;
  223. return {
  224. [`${componentCls}-root`]: {
  225. [`${componentCls}-wrap-rtl`]: {
  226. direction: 'rtl',
  227. [`${componentCls}-confirm-body`]: {
  228. direction: 'rtl'
  229. }
  230. }
  231. }
  232. };
  233. };
  234. const genResponsiveWidthStyle = token => {
  235. const {
  236. componentCls
  237. } = token;
  238. const oriGridMediaSizesMap = getMediaSize(token);
  239. const gridMediaSizesMap = Object.assign({}, oriGridMediaSizesMap);
  240. delete gridMediaSizesMap.xs;
  241. const cssVarPrefix = `--${componentCls.replace('.', '')}-`;
  242. const responsiveStyles = Object.keys(gridMediaSizesMap).map(key => ({
  243. [`@media (min-width: ${unit(gridMediaSizesMap[key])})`]: {
  244. width: `var(${cssVarPrefix}${key}-width)`
  245. }
  246. }));
  247. return {
  248. [`${componentCls}-root`]: {
  249. [componentCls]: [].concat(_toConsumableArray(Object.keys(oriGridMediaSizesMap).map((currentKey, index) => {
  250. const previousKey = Object.keys(oriGridMediaSizesMap)[index - 1];
  251. return previousKey ? {
  252. [`${cssVarPrefix}${currentKey}-width`]: `var(${cssVarPrefix}${previousKey}-width)`
  253. } : null;
  254. })), [{
  255. width: `var(${cssVarPrefix}xs-width)`
  256. }], _toConsumableArray(responsiveStyles))
  257. }
  258. };
  259. };
  260. // ============================== Export ==============================
  261. export const prepareToken = token => {
  262. const headerPaddingVertical = token.padding;
  263. const headerFontSize = token.fontSizeHeading5;
  264. const headerLineHeight = token.lineHeightHeading5;
  265. const modalToken = mergeToken(token, {
  266. modalHeaderHeight: token.calc(token.calc(headerLineHeight).mul(headerFontSize).equal()).add(token.calc(headerPaddingVertical).mul(2).equal()).equal(),
  267. modalFooterBorderColorSplit: token.colorSplit,
  268. modalFooterBorderStyle: token.lineType,
  269. modalFooterBorderWidth: token.lineWidth,
  270. modalCloseIconColor: token.colorIcon,
  271. modalCloseIconHoverColor: token.colorIconHover,
  272. modalCloseBtnSize: token.controlHeight,
  273. modalConfirmIconSize: token.fontHeight,
  274. modalTitleHeight: token.calc(token.titleFontSize).mul(token.titleLineHeight).equal()
  275. });
  276. return modalToken;
  277. };
  278. export const prepareComponentToken = token => ({
  279. footerBg: 'transparent',
  280. headerBg: token.colorBgElevated,
  281. titleLineHeight: token.lineHeightHeading5,
  282. titleFontSize: token.fontSizeHeading5,
  283. contentBg: token.colorBgElevated,
  284. titleColor: token.colorTextHeading,
  285. // internal
  286. contentPadding: token.wireframe ? 0 : `${unit(token.paddingMD)} ${unit(token.paddingContentHorizontalLG)}`,
  287. headerPadding: token.wireframe ? `${unit(token.padding)} ${unit(token.paddingLG)}` : 0,
  288. headerBorderBottom: token.wireframe ? `${unit(token.lineWidth)} ${token.lineType} ${token.colorSplit}` : 'none',
  289. headerMarginBottom: token.wireframe ? 0 : token.marginXS,
  290. bodyPadding: token.wireframe ? token.paddingLG : 0,
  291. footerPadding: token.wireframe ? `${unit(token.paddingXS)} ${unit(token.padding)}` : 0,
  292. footerBorderTop: token.wireframe ? `${unit(token.lineWidth)} ${token.lineType} ${token.colorSplit}` : 'none',
  293. footerBorderRadius: token.wireframe ? `0 0 ${unit(token.borderRadiusLG)} ${unit(token.borderRadiusLG)}` : 0,
  294. footerMarginTop: token.wireframe ? 0 : token.marginSM,
  295. confirmBodyPadding: token.wireframe ? `${unit(token.padding * 2)} ${unit(token.padding * 2)} ${unit(token.paddingLG)}` : 0,
  296. confirmIconMarginInlineEnd: token.wireframe ? token.margin : token.marginSM,
  297. confirmBtnsMarginTop: token.wireframe ? token.marginLG : token.marginSM
  298. });
  299. export default genStyleHooks('Modal', token => {
  300. const modalToken = prepareToken(token);
  301. return [genModalStyle(modalToken), genRTLStyle(modalToken), genModalMaskStyle(modalToken), initZoomMotion(modalToken, 'zoom'), genResponsiveWidthStyle(modalToken)];
  302. }, prepareComponentToken, {
  303. unitless: {
  304. titleLineHeight: true
  305. }
  306. });