index.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. import _extends from "@babel/runtime/helpers/esm/extends";
  2. import { genComponentStyleHook, mergeToken } from '../../theme/internal';
  3. import genGroupStyle from './group';
  4. import { genFocusStyle } from '../../style';
  5. import { genCompactItemStyle } from '../../style/compact-item';
  6. import { genCompactItemVerticalStyle } from '../../style/compact-item-vertical';
  7. // ============================== Shared ==============================
  8. const genSharedButtonStyle = token => {
  9. const {
  10. componentCls,
  11. iconCls
  12. } = token;
  13. return {
  14. [componentCls]: {
  15. outline: 'none',
  16. position: 'relative',
  17. display: 'inline-block',
  18. fontWeight: 400,
  19. whiteSpace: 'nowrap',
  20. textAlign: 'center',
  21. backgroundImage: 'none',
  22. backgroundColor: 'transparent',
  23. border: `${token.lineWidth}px ${token.lineType} transparent`,
  24. cursor: 'pointer',
  25. transition: `all ${token.motionDurationMid} ${token.motionEaseInOut}`,
  26. userSelect: 'none',
  27. touchAction: 'manipulation',
  28. lineHeight: token.lineHeight,
  29. color: token.colorText,
  30. '> span': {
  31. display: 'inline-block'
  32. },
  33. // Leave a space between icon and text.
  34. [`> ${iconCls} + span, > span + ${iconCls}`]: {
  35. marginInlineStart: token.marginXS
  36. },
  37. '> a': {
  38. color: 'currentColor'
  39. },
  40. '&:not(:disabled)': _extends({}, genFocusStyle(token)),
  41. // make `btn-icon-only` not too narrow
  42. [`&-icon-only${componentCls}-compact-item`]: {
  43. flex: 'none'
  44. },
  45. // Special styles for Primary Button
  46. [`&-compact-item${componentCls}-primary`]: {
  47. [`&:not([disabled]) + ${componentCls}-compact-item${componentCls}-primary:not([disabled])`]: {
  48. position: 'relative',
  49. '&:before': {
  50. position: 'absolute',
  51. top: -token.lineWidth,
  52. insetInlineStart: -token.lineWidth,
  53. display: 'inline-block',
  54. width: token.lineWidth,
  55. height: `calc(100% + ${token.lineWidth * 2}px)`,
  56. backgroundColor: token.colorPrimaryHover,
  57. content: '""'
  58. }
  59. }
  60. },
  61. // Special styles for Primary Button
  62. '&-compact-vertical-item': {
  63. [`&${componentCls}-primary`]: {
  64. [`&:not([disabled]) + ${componentCls}-compact-vertical-item${componentCls}-primary:not([disabled])`]: {
  65. position: 'relative',
  66. '&:before': {
  67. position: 'absolute',
  68. top: -token.lineWidth,
  69. insetInlineStart: -token.lineWidth,
  70. display: 'inline-block',
  71. width: `calc(100% + ${token.lineWidth * 2}px)`,
  72. height: token.lineWidth,
  73. backgroundColor: token.colorPrimaryHover,
  74. content: '""'
  75. }
  76. }
  77. }
  78. }
  79. }
  80. };
  81. };
  82. const genHoverActiveButtonStyle = (hoverStyle, activeStyle) => ({
  83. '&:not(:disabled)': {
  84. '&:hover': hoverStyle,
  85. '&:active': activeStyle
  86. }
  87. });
  88. // ============================== Shape ===============================
  89. const genCircleButtonStyle = token => ({
  90. minWidth: token.controlHeight,
  91. paddingInlineStart: 0,
  92. paddingInlineEnd: 0,
  93. borderRadius: '50%'
  94. });
  95. const genRoundButtonStyle = token => ({
  96. borderRadius: token.controlHeight,
  97. paddingInlineStart: token.controlHeight / 2,
  98. paddingInlineEnd: token.controlHeight / 2
  99. });
  100. // =============================== Type ===============================
  101. const genDisabledStyle = token => ({
  102. cursor: 'not-allowed',
  103. borderColor: token.colorBorder,
  104. color: token.colorTextDisabled,
  105. backgroundColor: token.colorBgContainerDisabled,
  106. boxShadow: 'none'
  107. });
  108. const genGhostButtonStyle = (btnCls, textColor, borderColor, textColorDisabled, borderColorDisabled, hoverStyle, activeStyle) => ({
  109. [`&${btnCls}-background-ghost`]: _extends(_extends({
  110. color: textColor || undefined,
  111. backgroundColor: 'transparent',
  112. borderColor: borderColor || undefined,
  113. boxShadow: 'none'
  114. }, genHoverActiveButtonStyle(_extends({
  115. backgroundColor: 'transparent'
  116. }, hoverStyle), _extends({
  117. backgroundColor: 'transparent'
  118. }, activeStyle))), {
  119. '&:disabled': {
  120. cursor: 'not-allowed',
  121. color: textColorDisabled || undefined,
  122. borderColor: borderColorDisabled || undefined
  123. }
  124. })
  125. });
  126. const genSolidDisabledButtonStyle = token => ({
  127. '&:disabled': _extends({}, genDisabledStyle(token))
  128. });
  129. const genSolidButtonStyle = token => _extends({}, genSolidDisabledButtonStyle(token));
  130. const genPureDisabledButtonStyle = token => ({
  131. '&:disabled': {
  132. cursor: 'not-allowed',
  133. color: token.colorTextDisabled
  134. }
  135. });
  136. // Type: Default
  137. const genDefaultButtonStyle = token => _extends(_extends(_extends(_extends(_extends({}, genSolidButtonStyle(token)), {
  138. backgroundColor: token.colorBgContainer,
  139. borderColor: token.colorBorder,
  140. boxShadow: `0 ${token.controlOutlineWidth}px 0 ${token.controlTmpOutline}`
  141. }), genHoverActiveButtonStyle({
  142. color: token.colorPrimaryHover,
  143. borderColor: token.colorPrimaryHover
  144. }, {
  145. color: token.colorPrimaryActive,
  146. borderColor: token.colorPrimaryActive
  147. })), genGhostButtonStyle(token.componentCls, token.colorBgContainer, token.colorBgContainer, token.colorTextDisabled, token.colorBorder)), {
  148. [`&${token.componentCls}-dangerous`]: _extends(_extends(_extends({
  149. color: token.colorError,
  150. borderColor: token.colorError
  151. }, genHoverActiveButtonStyle({
  152. color: token.colorErrorHover,
  153. borderColor: token.colorErrorBorderHover
  154. }, {
  155. color: token.colorErrorActive,
  156. borderColor: token.colorErrorActive
  157. })), genGhostButtonStyle(token.componentCls, token.colorError, token.colorError, token.colorTextDisabled, token.colorBorder)), genSolidDisabledButtonStyle(token))
  158. });
  159. // Type: Primary
  160. const genPrimaryButtonStyle = token => _extends(_extends(_extends(_extends(_extends({}, genSolidButtonStyle(token)), {
  161. color: token.colorTextLightSolid,
  162. backgroundColor: token.colorPrimary,
  163. boxShadow: `0 ${token.controlOutlineWidth}px 0 ${token.controlOutline}`
  164. }), genHoverActiveButtonStyle({
  165. color: token.colorTextLightSolid,
  166. backgroundColor: token.colorPrimaryHover
  167. }, {
  168. color: token.colorTextLightSolid,
  169. backgroundColor: token.colorPrimaryActive
  170. })), genGhostButtonStyle(token.componentCls, token.colorPrimary, token.colorPrimary, token.colorTextDisabled, token.colorBorder, {
  171. color: token.colorPrimaryHover,
  172. borderColor: token.colorPrimaryHover
  173. }, {
  174. color: token.colorPrimaryActive,
  175. borderColor: token.colorPrimaryActive
  176. })), {
  177. [`&${token.componentCls}-dangerous`]: _extends(_extends(_extends({
  178. backgroundColor: token.colorError,
  179. boxShadow: `0 ${token.controlOutlineWidth}px 0 ${token.colorErrorOutline}`
  180. }, genHoverActiveButtonStyle({
  181. backgroundColor: token.colorErrorHover
  182. }, {
  183. backgroundColor: token.colorErrorActive
  184. })), genGhostButtonStyle(token.componentCls, token.colorError, token.colorError, token.colorTextDisabled, token.colorBorder, {
  185. color: token.colorErrorHover,
  186. borderColor: token.colorErrorHover
  187. }, {
  188. color: token.colorErrorActive,
  189. borderColor: token.colorErrorActive
  190. })), genSolidDisabledButtonStyle(token))
  191. });
  192. // Type: Dashed
  193. const genDashedButtonStyle = token => _extends(_extends({}, genDefaultButtonStyle(token)), {
  194. borderStyle: 'dashed'
  195. });
  196. // Type: Link
  197. const genLinkButtonStyle = token => _extends(_extends(_extends({
  198. color: token.colorLink
  199. }, genHoverActiveButtonStyle({
  200. color: token.colorLinkHover
  201. }, {
  202. color: token.colorLinkActive
  203. })), genPureDisabledButtonStyle(token)), {
  204. [`&${token.componentCls}-dangerous`]: _extends(_extends({
  205. color: token.colorError
  206. }, genHoverActiveButtonStyle({
  207. color: token.colorErrorHover
  208. }, {
  209. color: token.colorErrorActive
  210. })), genPureDisabledButtonStyle(token))
  211. });
  212. // Type: Text
  213. const genTextButtonStyle = token => _extends(_extends(_extends({}, genHoverActiveButtonStyle({
  214. color: token.colorText,
  215. backgroundColor: token.colorBgTextHover
  216. }, {
  217. color: token.colorText,
  218. backgroundColor: token.colorBgTextActive
  219. })), genPureDisabledButtonStyle(token)), {
  220. [`&${token.componentCls}-dangerous`]: _extends(_extends({
  221. color: token.colorError
  222. }, genPureDisabledButtonStyle(token)), genHoverActiveButtonStyle({
  223. color: token.colorErrorHover,
  224. backgroundColor: token.colorErrorBg
  225. }, {
  226. color: token.colorErrorHover,
  227. backgroundColor: token.colorErrorBg
  228. }))
  229. });
  230. // Href and Disabled
  231. const genDisabledButtonStyle = token => _extends(_extends({}, genDisabledStyle(token)), {
  232. [`&${token.componentCls}:hover`]: _extends({}, genDisabledStyle(token))
  233. });
  234. const genTypeButtonStyle = token => {
  235. const {
  236. componentCls
  237. } = token;
  238. return {
  239. [`${componentCls}-default`]: genDefaultButtonStyle(token),
  240. [`${componentCls}-primary`]: genPrimaryButtonStyle(token),
  241. [`${componentCls}-dashed`]: genDashedButtonStyle(token),
  242. [`${componentCls}-link`]: genLinkButtonStyle(token),
  243. [`${componentCls}-text`]: genTextButtonStyle(token),
  244. [`${componentCls}-disabled`]: genDisabledButtonStyle(token)
  245. };
  246. };
  247. // =============================== Size ===============================
  248. const genSizeButtonStyle = function (token) {
  249. let sizePrefixCls = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
  250. const {
  251. componentCls,
  252. iconCls,
  253. controlHeight,
  254. fontSize,
  255. lineHeight,
  256. lineWidth,
  257. borderRadius,
  258. buttonPaddingHorizontal
  259. } = token;
  260. const paddingVertical = Math.max(0, (controlHeight - fontSize * lineHeight) / 2 - lineWidth);
  261. const paddingHorizontal = buttonPaddingHorizontal - lineWidth;
  262. const iconOnlyCls = `${componentCls}-icon-only`;
  263. return [
  264. // Size
  265. {
  266. [`${componentCls}${sizePrefixCls}`]: {
  267. fontSize,
  268. height: controlHeight,
  269. padding: `${paddingVertical}px ${paddingHorizontal}px`,
  270. borderRadius,
  271. [`&${iconOnlyCls}`]: {
  272. width: controlHeight,
  273. paddingInlineStart: 0,
  274. paddingInlineEnd: 0,
  275. [`&${componentCls}-round`]: {
  276. width: 'auto'
  277. },
  278. '> span': {
  279. transform: 'scale(1.143)' // 14px -> 16px
  280. }
  281. },
  282. // Loading
  283. [`&${componentCls}-loading`]: {
  284. opacity: token.opacityLoading,
  285. cursor: 'default'
  286. },
  287. [`${componentCls}-loading-icon`]: {
  288. transition: `width ${token.motionDurationSlow} ${token.motionEaseInOut}, opacity ${token.motionDurationSlow} ${token.motionEaseInOut}`
  289. },
  290. [`&:not(${iconOnlyCls}) ${componentCls}-loading-icon > ${iconCls}`]: {
  291. marginInlineEnd: token.marginXS
  292. }
  293. }
  294. },
  295. // Shape - patch prefixCls again to override solid border radius style
  296. {
  297. [`${componentCls}${componentCls}-circle${sizePrefixCls}`]: genCircleButtonStyle(token)
  298. }, {
  299. [`${componentCls}${componentCls}-round${sizePrefixCls}`]: genRoundButtonStyle(token)
  300. }];
  301. };
  302. const genSizeBaseButtonStyle = token => genSizeButtonStyle(token);
  303. const genSizeSmallButtonStyle = token => {
  304. const smallToken = mergeToken(token, {
  305. controlHeight: token.controlHeightSM,
  306. padding: token.paddingXS,
  307. buttonPaddingHorizontal: 8,
  308. borderRadius: token.borderRadiusSM
  309. });
  310. return genSizeButtonStyle(smallToken, `${token.componentCls}-sm`);
  311. };
  312. const genSizeLargeButtonStyle = token => {
  313. const largeToken = mergeToken(token, {
  314. controlHeight: token.controlHeightLG,
  315. fontSize: token.fontSizeLG,
  316. borderRadius: token.borderRadiusLG
  317. });
  318. return genSizeButtonStyle(largeToken, `${token.componentCls}-lg`);
  319. };
  320. const genBlockButtonStyle = token => {
  321. const {
  322. componentCls
  323. } = token;
  324. return {
  325. [componentCls]: {
  326. [`&${componentCls}-block`]: {
  327. width: '100%'
  328. }
  329. }
  330. };
  331. };
  332. // ============================== Export ==============================
  333. export default genComponentStyleHook('Button', token => {
  334. const {
  335. controlTmpOutline,
  336. paddingContentHorizontal
  337. } = token;
  338. const buttonToken = mergeToken(token, {
  339. colorOutlineDefault: controlTmpOutline,
  340. buttonPaddingHorizontal: paddingContentHorizontal
  341. });
  342. return [
  343. // Shared
  344. genSharedButtonStyle(buttonToken),
  345. // Size
  346. genSizeSmallButtonStyle(buttonToken), genSizeBaseButtonStyle(buttonToken), genSizeLargeButtonStyle(buttonToken),
  347. // Block
  348. genBlockButtonStyle(buttonToken),
  349. // Group (type, ghost, danger, disabled, loading)
  350. genTypeButtonStyle(buttonToken),
  351. // Button Group
  352. genGroupStyle(buttonToken),
  353. // Space Compact
  354. genCompactItemStyle(token, {
  355. focus: false
  356. }), genCompactItemVerticalStyle(token)];
  357. });