index.js 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. import _extends from "@babel/runtime/helpers/esm/extends";
  2. import { Keyframes } from '../../_util/cssinjs';
  3. import { genComponentStyleHook, mergeToken } from '../../theme/internal';
  4. import { genFocusOutline, resetComponent } from '../../style';
  5. // ============================== Motion ==============================
  6. const antCheckboxEffect = new Keyframes('antCheckboxEffect', {
  7. '0%': {
  8. transform: 'scale(1)',
  9. opacity: 0.5
  10. },
  11. '100%': {
  12. transform: 'scale(1.6)',
  13. opacity: 0
  14. }
  15. });
  16. // ============================== Styles ==============================
  17. export const genCheckboxStyle = token => {
  18. const {
  19. checkboxCls
  20. } = token;
  21. const wrapperCls = `${checkboxCls}-wrapper`;
  22. return [
  23. // ===================== Basic =====================
  24. {
  25. // Group
  26. [`${checkboxCls}-group`]: _extends(_extends({}, resetComponent(token)), {
  27. display: 'inline-flex',
  28. flexWrap: 'wrap',
  29. columnGap: token.marginXS,
  30. // Group > Grid
  31. [`> ${token.antCls}-row`]: {
  32. flex: 1
  33. }
  34. }),
  35. // Wrapper
  36. [wrapperCls]: _extends(_extends({}, resetComponent(token)), {
  37. display: 'inline-flex',
  38. alignItems: 'baseline',
  39. cursor: 'pointer',
  40. // Fix checkbox & radio in flex align #30260
  41. '&:after': {
  42. display: 'inline-block',
  43. width: 0,
  44. overflow: 'hidden',
  45. content: "'\\a0'"
  46. },
  47. // Checkbox near checkbox
  48. [`& + ${wrapperCls}`]: {
  49. marginInlineStart: 0
  50. },
  51. [`&${wrapperCls}-in-form-item`]: {
  52. 'input[type="checkbox"]': {
  53. width: 14,
  54. height: 14 // FIXME: magic
  55. }
  56. }
  57. }),
  58. // Wrapper > Checkbox
  59. [checkboxCls]: _extends(_extends({}, resetComponent(token)), {
  60. position: 'relative',
  61. whiteSpace: 'nowrap',
  62. lineHeight: 1,
  63. cursor: 'pointer',
  64. // To make alignment right when `controlHeight` is changed
  65. // Ref: https://github.com/ant-design/ant-design/issues/41564
  66. alignSelf: 'center',
  67. // Wrapper > Checkbox > input
  68. [`${checkboxCls}-input`]: {
  69. position: 'absolute',
  70. // Since baseline align will get additional space offset,
  71. // we need to move input to top to make it align with text.
  72. // Ref: https://github.com/ant-design/ant-design/issues/38926#issuecomment-1486137799
  73. inset: 0,
  74. zIndex: 1,
  75. cursor: 'pointer',
  76. opacity: 0,
  77. margin: 0,
  78. [`&:focus-visible + ${checkboxCls}-inner`]: _extends({}, genFocusOutline(token))
  79. },
  80. // Wrapper > Checkbox > inner
  81. [`${checkboxCls}-inner`]: {
  82. boxSizing: 'border-box',
  83. position: 'relative',
  84. top: 0,
  85. insetInlineStart: 0,
  86. display: 'block',
  87. width: token.checkboxSize,
  88. height: token.checkboxSize,
  89. direction: 'ltr',
  90. backgroundColor: token.colorBgContainer,
  91. border: `${token.lineWidth}px ${token.lineType} ${token.colorBorder}`,
  92. borderRadius: token.borderRadiusSM,
  93. borderCollapse: 'separate',
  94. transition: `all ${token.motionDurationSlow}`,
  95. '&:after': {
  96. boxSizing: 'border-box',
  97. position: 'absolute',
  98. top: '50%',
  99. insetInlineStart: '21.5%',
  100. display: 'table',
  101. width: token.checkboxSize / 14 * 5,
  102. height: token.checkboxSize / 14 * 8,
  103. border: `${token.lineWidthBold}px solid ${token.colorWhite}`,
  104. borderTop: 0,
  105. borderInlineStart: 0,
  106. transform: 'rotate(45deg) scale(0) translate(-50%,-50%)',
  107. opacity: 0,
  108. content: '""',
  109. transition: `all ${token.motionDurationFast} ${token.motionEaseInBack}, opacity ${token.motionDurationFast}`
  110. }
  111. },
  112. // Wrapper > Checkbox + Text
  113. '& + span': {
  114. paddingInlineStart: token.paddingXS,
  115. paddingInlineEnd: token.paddingXS
  116. }
  117. })
  118. },
  119. // ================= Indeterminate =================
  120. {
  121. [checkboxCls]: {
  122. '&-indeterminate': {
  123. // Wrapper > Checkbox > inner
  124. [`${checkboxCls}-inner`]: {
  125. '&:after': {
  126. top: '50%',
  127. insetInlineStart: '50%',
  128. width: token.fontSizeLG / 2,
  129. height: token.fontSizeLG / 2,
  130. backgroundColor: token.colorPrimary,
  131. border: 0,
  132. transform: 'translate(-50%, -50%) scale(1)',
  133. opacity: 1,
  134. content: '""'
  135. }
  136. }
  137. }
  138. }
  139. },
  140. // ===================== Hover =====================
  141. {
  142. // Wrapper
  143. [`${wrapperCls}:hover ${checkboxCls}:after`]: {
  144. visibility: 'visible'
  145. },
  146. // Wrapper & Wrapper > Checkbox
  147. [`
  148. ${wrapperCls}:not(${wrapperCls}-disabled),
  149. ${checkboxCls}:not(${checkboxCls}-disabled)
  150. `]: {
  151. [`&:hover ${checkboxCls}-inner`]: {
  152. borderColor: token.colorPrimary
  153. }
  154. },
  155. [`${wrapperCls}:not(${wrapperCls}-disabled)`]: {
  156. [`&:hover ${checkboxCls}-checked:not(${checkboxCls}-disabled) ${checkboxCls}-inner`]: {
  157. backgroundColor: token.colorPrimaryHover,
  158. borderColor: 'transparent'
  159. },
  160. [`&:hover ${checkboxCls}-checked:not(${checkboxCls}-disabled):after`]: {
  161. borderColor: token.colorPrimaryHover
  162. }
  163. }
  164. },
  165. // ==================== Checked ====================
  166. {
  167. // Wrapper > Checkbox
  168. [`${checkboxCls}-checked`]: {
  169. [`${checkboxCls}-inner`]: {
  170. backgroundColor: token.colorPrimary,
  171. borderColor: token.colorPrimary,
  172. '&:after': {
  173. opacity: 1,
  174. transform: 'rotate(45deg) scale(1) translate(-50%,-50%)',
  175. transition: `all ${token.motionDurationMid} ${token.motionEaseOutBack} ${token.motionDurationFast}`
  176. }
  177. },
  178. // Checked Effect
  179. '&:after': {
  180. position: 'absolute',
  181. top: 0,
  182. insetInlineStart: 0,
  183. width: '100%',
  184. height: '100%',
  185. borderRadius: token.borderRadiusSM,
  186. visibility: 'hidden',
  187. border: `${token.lineWidthBold}px solid ${token.colorPrimary}`,
  188. animationName: antCheckboxEffect,
  189. animationDuration: token.motionDurationSlow,
  190. animationTimingFunction: 'ease-in-out',
  191. animationFillMode: 'backwards',
  192. content: '""',
  193. transition: `all ${token.motionDurationSlow}`
  194. }
  195. },
  196. [`
  197. ${wrapperCls}-checked:not(${wrapperCls}-disabled),
  198. ${checkboxCls}-checked:not(${checkboxCls}-disabled)
  199. `]: {
  200. [`&:hover ${checkboxCls}-inner`]: {
  201. backgroundColor: token.colorPrimaryHover,
  202. borderColor: 'transparent'
  203. },
  204. [`&:hover ${checkboxCls}:after`]: {
  205. borderColor: token.colorPrimaryHover
  206. }
  207. }
  208. },
  209. // ==================== Disable ====================
  210. {
  211. // Wrapper
  212. [`${wrapperCls}-disabled`]: {
  213. cursor: 'not-allowed'
  214. },
  215. // Wrapper > Checkbox
  216. [`${checkboxCls}-disabled`]: {
  217. // Wrapper > Checkbox > input
  218. [`&, ${checkboxCls}-input`]: {
  219. cursor: 'not-allowed',
  220. // Disabled for native input to enable Tooltip event handler
  221. // ref: https://github.com/ant-design/ant-design/issues/39822#issuecomment-1365075901
  222. pointerEvents: 'none'
  223. },
  224. // Wrapper > Checkbox > inner
  225. [`${checkboxCls}-inner`]: {
  226. background: token.colorBgContainerDisabled,
  227. borderColor: token.colorBorder,
  228. '&:after': {
  229. borderColor: token.colorTextDisabled
  230. }
  231. },
  232. '&:after': {
  233. display: 'none'
  234. },
  235. '& + span': {
  236. color: token.colorTextDisabled
  237. },
  238. [`&${checkboxCls}-indeterminate ${checkboxCls}-inner::after`]: {
  239. background: token.colorTextDisabled
  240. }
  241. }
  242. }];
  243. };
  244. // ============================== Export ==============================
  245. export function getStyle(prefixCls, token) {
  246. const checkboxToken = mergeToken(token, {
  247. checkboxCls: `.${prefixCls}`,
  248. checkboxSize: token.controlInteractiveSize
  249. });
  250. return [genCheckboxStyle(checkboxToken)];
  251. }
  252. export default genComponentStyleHook('Checkbox', (token, _ref) => {
  253. let {
  254. prefixCls
  255. } = _ref;
  256. return [getStyle(prefixCls, token)];
  257. });