index.js 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. import _extends from "@babel/runtime/helpers/esm/extends";
  2. import { TinyColor } from '@ctrl/tinycolor';
  3. import { genComponentStyleHook, mergeToken } from '../../theme/internal';
  4. import { genFocusStyle, resetComponent } from '../../style';
  5. const genSwitchSmallStyle = token => {
  6. const {
  7. componentCls
  8. } = token;
  9. const switchInnerCls = `${componentCls}-inner`;
  10. return {
  11. [componentCls]: {
  12. [`&${componentCls}-small`]: {
  13. minWidth: token.switchMinWidthSM,
  14. height: token.switchHeightSM,
  15. lineHeight: `${token.switchHeightSM}px`,
  16. [`${componentCls}-inner`]: {
  17. paddingInlineStart: token.switchInnerMarginMaxSM,
  18. paddingInlineEnd: token.switchInnerMarginMinSM,
  19. [`${switchInnerCls}-checked`]: {
  20. marginInlineStart: `calc(-100% + ${token.switchPinSizeSM + token.switchPadding * 2}px - ${token.switchInnerMarginMaxSM * 2}px)`,
  21. marginInlineEnd: `calc(100% - ${token.switchPinSizeSM + token.switchPadding * 2}px + ${token.switchInnerMarginMaxSM * 2}px)`
  22. },
  23. [`${switchInnerCls}-unchecked`]: {
  24. marginTop: -token.switchHeightSM,
  25. marginInlineStart: 0,
  26. marginInlineEnd: 0
  27. }
  28. },
  29. [`${componentCls}-handle`]: {
  30. width: token.switchPinSizeSM,
  31. height: token.switchPinSizeSM
  32. },
  33. [`${componentCls}-loading-icon`]: {
  34. top: (token.switchPinSizeSM - token.switchLoadingIconSize) / 2,
  35. fontSize: token.switchLoadingIconSize
  36. },
  37. [`&${componentCls}-checked`]: {
  38. [`${componentCls}-inner`]: {
  39. paddingInlineStart: token.switchInnerMarginMinSM,
  40. paddingInlineEnd: token.switchInnerMarginMaxSM,
  41. [`${switchInnerCls}-checked`]: {
  42. marginInlineStart: 0,
  43. marginInlineEnd: 0
  44. },
  45. [`${switchInnerCls}-unchecked`]: {
  46. marginInlineStart: `calc(100% - ${token.switchPinSizeSM + token.switchPadding * 2}px + ${token.switchInnerMarginMaxSM * 2}px)`,
  47. marginInlineEnd: `calc(-100% + ${token.switchPinSizeSM + token.switchPadding * 2}px - ${token.switchInnerMarginMaxSM * 2}px)`
  48. }
  49. },
  50. [`${componentCls}-handle`]: {
  51. insetInlineStart: `calc(100% - ${token.switchPinSizeSM + token.switchPadding}px)`
  52. }
  53. },
  54. [`&:not(${componentCls}-disabled):active`]: {
  55. [`&:not(${componentCls}-checked) ${switchInnerCls}`]: {
  56. [`${switchInnerCls}-unchecked`]: {
  57. marginInlineStart: token.marginXXS / 2,
  58. marginInlineEnd: -token.marginXXS / 2
  59. }
  60. },
  61. [`&${componentCls}-checked ${switchInnerCls}`]: {
  62. [`${switchInnerCls}-checked`]: {
  63. marginInlineStart: -token.marginXXS / 2,
  64. marginInlineEnd: token.marginXXS / 2
  65. }
  66. }
  67. }
  68. }
  69. }
  70. };
  71. };
  72. const genSwitchLoadingStyle = token => {
  73. const {
  74. componentCls
  75. } = token;
  76. return {
  77. [componentCls]: {
  78. [`${componentCls}-loading-icon${token.iconCls}`]: {
  79. position: 'relative',
  80. top: (token.switchPinSize - token.fontSize) / 2,
  81. color: token.switchLoadingIconColor,
  82. verticalAlign: 'top'
  83. },
  84. [`&${componentCls}-checked ${componentCls}-loading-icon`]: {
  85. color: token.switchColor
  86. }
  87. }
  88. };
  89. };
  90. const genSwitchHandleStyle = token => {
  91. const {
  92. componentCls
  93. } = token;
  94. const switchHandleCls = `${componentCls}-handle`;
  95. return {
  96. [componentCls]: {
  97. [switchHandleCls]: {
  98. position: 'absolute',
  99. top: token.switchPadding,
  100. insetInlineStart: token.switchPadding,
  101. width: token.switchPinSize,
  102. height: token.switchPinSize,
  103. transition: `all ${token.switchDuration} ease-in-out`,
  104. '&::before': {
  105. position: 'absolute',
  106. top: 0,
  107. insetInlineEnd: 0,
  108. bottom: 0,
  109. insetInlineStart: 0,
  110. backgroundColor: token.colorWhite,
  111. borderRadius: token.switchPinSize / 2,
  112. boxShadow: token.switchHandleShadow,
  113. transition: `all ${token.switchDuration} ease-in-out`,
  114. content: '""'
  115. }
  116. },
  117. [`&${componentCls}-checked ${switchHandleCls}`]: {
  118. insetInlineStart: `calc(100% - ${token.switchPinSize + token.switchPadding}px)`
  119. },
  120. [`&:not(${componentCls}-disabled):active`]: {
  121. [`${switchHandleCls}::before`]: {
  122. insetInlineEnd: token.switchHandleActiveInset,
  123. insetInlineStart: 0
  124. },
  125. [`&${componentCls}-checked ${switchHandleCls}::before`]: {
  126. insetInlineEnd: 0,
  127. insetInlineStart: token.switchHandleActiveInset
  128. }
  129. }
  130. }
  131. };
  132. };
  133. const genSwitchInnerStyle = token => {
  134. const {
  135. componentCls
  136. } = token;
  137. const switchInnerCls = `${componentCls}-inner`;
  138. return {
  139. [componentCls]: {
  140. [switchInnerCls]: {
  141. display: 'block',
  142. overflow: 'hidden',
  143. borderRadius: 100,
  144. height: '100%',
  145. paddingInlineStart: token.switchInnerMarginMax,
  146. paddingInlineEnd: token.switchInnerMarginMin,
  147. transition: `padding-inline-start ${token.switchDuration} ease-in-out, padding-inline-end ${token.switchDuration} ease-in-out`,
  148. [`${switchInnerCls}-checked, ${switchInnerCls}-unchecked`]: {
  149. display: 'block',
  150. color: token.colorTextLightSolid,
  151. fontSize: token.fontSizeSM,
  152. transition: `margin-inline-start ${token.switchDuration} ease-in-out, margin-inline-end ${token.switchDuration} ease-in-out`,
  153. pointerEvents: 'none'
  154. },
  155. [`${switchInnerCls}-checked`]: {
  156. marginInlineStart: `calc(-100% + ${token.switchPinSize + token.switchPadding * 2}px - ${token.switchInnerMarginMax * 2}px)`,
  157. marginInlineEnd: `calc(100% - ${token.switchPinSize + token.switchPadding * 2}px + ${token.switchInnerMarginMax * 2}px)`
  158. },
  159. [`${switchInnerCls}-unchecked`]: {
  160. marginTop: -token.switchHeight,
  161. marginInlineStart: 0,
  162. marginInlineEnd: 0
  163. }
  164. },
  165. [`&${componentCls}-checked ${switchInnerCls}`]: {
  166. paddingInlineStart: token.switchInnerMarginMin,
  167. paddingInlineEnd: token.switchInnerMarginMax,
  168. [`${switchInnerCls}-checked`]: {
  169. marginInlineStart: 0,
  170. marginInlineEnd: 0
  171. },
  172. [`${switchInnerCls}-unchecked`]: {
  173. marginInlineStart: `calc(100% - ${token.switchPinSize + token.switchPadding * 2}px + ${token.switchInnerMarginMax * 2}px)`,
  174. marginInlineEnd: `calc(-100% + ${token.switchPinSize + token.switchPadding * 2}px - ${token.switchInnerMarginMax * 2}px)`
  175. }
  176. },
  177. [`&:not(${componentCls}-disabled):active`]: {
  178. [`&:not(${componentCls}-checked) ${switchInnerCls}`]: {
  179. [`${switchInnerCls}-unchecked`]: {
  180. marginInlineStart: token.switchPadding * 2,
  181. marginInlineEnd: -token.switchPadding * 2
  182. }
  183. },
  184. [`&${componentCls}-checked ${switchInnerCls}`]: {
  185. [`${switchInnerCls}-checked`]: {
  186. marginInlineStart: -token.switchPadding * 2,
  187. marginInlineEnd: token.switchPadding * 2
  188. }
  189. }
  190. }
  191. }
  192. };
  193. };
  194. const genSwitchStyle = token => {
  195. const {
  196. componentCls
  197. } = token;
  198. return {
  199. [componentCls]: _extends(_extends(_extends(_extends({}, resetComponent(token)), {
  200. position: 'relative',
  201. display: 'inline-block',
  202. boxSizing: 'border-box',
  203. minWidth: token.switchMinWidth,
  204. height: token.switchHeight,
  205. lineHeight: `${token.switchHeight}px`,
  206. verticalAlign: 'middle',
  207. background: token.colorTextQuaternary,
  208. border: '0',
  209. borderRadius: 100,
  210. cursor: 'pointer',
  211. transition: `all ${token.motionDurationMid}`,
  212. userSelect: 'none',
  213. [`&:hover:not(${componentCls}-disabled)`]: {
  214. background: token.colorTextTertiary
  215. }
  216. }), genFocusStyle(token)), {
  217. [`&${componentCls}-checked`]: {
  218. background: token.switchColor,
  219. [`&:hover:not(${componentCls}-disabled)`]: {
  220. background: token.colorPrimaryHover
  221. }
  222. },
  223. [`&${componentCls}-loading, &${componentCls}-disabled`]: {
  224. cursor: 'not-allowed',
  225. opacity: token.switchDisabledOpacity,
  226. '*': {
  227. boxShadow: 'none',
  228. cursor: 'not-allowed'
  229. }
  230. },
  231. // rtl style
  232. [`&${componentCls}-rtl`]: {
  233. direction: 'rtl'
  234. }
  235. })
  236. };
  237. };
  238. // ============================== Export ==============================
  239. export default genComponentStyleHook('Switch', token => {
  240. const switchHeight = token.fontSize * token.lineHeight;
  241. const switchHeightSM = token.controlHeight / 2;
  242. const switchPadding = 2; // This is magic
  243. const switchPinSize = switchHeight - switchPadding * 2;
  244. const switchPinSizeSM = switchHeightSM - switchPadding * 2;
  245. const switchToken = mergeToken(token, {
  246. switchMinWidth: switchPinSize * 2 + switchPadding * 4,
  247. switchHeight,
  248. switchDuration: token.motionDurationMid,
  249. switchColor: token.colorPrimary,
  250. switchDisabledOpacity: token.opacityLoading,
  251. switchInnerMarginMin: switchPinSize / 2,
  252. switchInnerMarginMax: switchPinSize + switchPadding + switchPadding * 2,
  253. switchPadding,
  254. switchPinSize,
  255. switchBg: token.colorBgContainer,
  256. switchMinWidthSM: switchPinSizeSM * 2 + switchPadding * 2,
  257. switchHeightSM,
  258. switchInnerMarginMinSM: switchPinSizeSM / 2,
  259. switchInnerMarginMaxSM: switchPinSizeSM + switchPadding + switchPadding * 2,
  260. switchPinSizeSM,
  261. switchHandleShadow: `0 2px 4px 0 ${new TinyColor('#00230b').setAlpha(0.2).toRgbString()}`,
  262. switchLoadingIconSize: token.fontSizeIcon * 0.75,
  263. switchLoadingIconColor: `rgba(0, 0, 0, ${token.opacityLoading})`,
  264. switchHandleActiveInset: '-30%'
  265. });
  266. return [genSwitchStyle(switchToken),
  267. // inner style
  268. genSwitchInnerStyle(switchToken),
  269. // handle style
  270. genSwitchHandleStyle(switchToken),
  271. // loading style
  272. genSwitchLoadingStyle(switchToken),
  273. // small style
  274. genSwitchSmallStyle(switchToken)];
  275. });