index.js 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. import { unit } from '@ant-design/cssinjs';
  2. import { genFocusStyle, resetComponent, resetIcon } from '../../style';
  3. import { genCollapseMotion } from '../../style/motion';
  4. import { genStyleHooks, mergeToken } from '../../theme/internal';
  5. export const genBaseStyle = token => {
  6. const {
  7. componentCls,
  8. contentBg,
  9. padding,
  10. headerBg,
  11. headerPadding,
  12. collapseHeaderPaddingSM,
  13. collapseHeaderPaddingLG,
  14. collapsePanelBorderRadius,
  15. lineWidth,
  16. lineType,
  17. colorBorder,
  18. colorText,
  19. colorTextHeading,
  20. colorTextDisabled,
  21. fontSizeLG,
  22. lineHeight,
  23. lineHeightLG,
  24. marginSM,
  25. paddingSM,
  26. paddingLG,
  27. paddingXS,
  28. motionDurationSlow,
  29. fontSizeIcon,
  30. contentPadding,
  31. fontHeight,
  32. fontHeightLG
  33. } = token;
  34. const borderBase = `${unit(lineWidth)} ${lineType} ${colorBorder}`;
  35. return {
  36. [componentCls]: Object.assign(Object.assign({}, resetComponent(token)), {
  37. backgroundColor: headerBg,
  38. border: borderBase,
  39. borderRadius: collapsePanelBorderRadius,
  40. '&-rtl': {
  41. direction: 'rtl'
  42. },
  43. [`& > ${componentCls}-item`]: {
  44. borderBottom: borderBase,
  45. '&:first-child': {
  46. [`
  47. &,
  48. & > ${componentCls}-header`]: {
  49. borderRadius: `${unit(collapsePanelBorderRadius)} ${unit(collapsePanelBorderRadius)} 0 0`
  50. }
  51. },
  52. '&:last-child': {
  53. [`
  54. &,
  55. & > ${componentCls}-header`]: {
  56. borderRadius: `0 0 ${unit(collapsePanelBorderRadius)} ${unit(collapsePanelBorderRadius)}`
  57. }
  58. },
  59. [`> ${componentCls}-header`]: Object.assign(Object.assign({
  60. position: 'relative',
  61. display: 'flex',
  62. flexWrap: 'nowrap',
  63. alignItems: 'flex-start',
  64. padding: headerPadding,
  65. color: colorTextHeading,
  66. lineHeight,
  67. cursor: 'pointer',
  68. transition: `all ${motionDurationSlow}, visibility 0s`
  69. }, genFocusStyle(token)), {
  70. [`> ${componentCls}-header-text`]: {
  71. flex: 'auto'
  72. },
  73. // >>>>> Arrow
  74. [`${componentCls}-expand-icon`]: {
  75. height: fontHeight,
  76. display: 'flex',
  77. alignItems: 'center',
  78. paddingInlineEnd: marginSM
  79. },
  80. [`${componentCls}-arrow`]: Object.assign(Object.assign({}, resetIcon()), {
  81. fontSize: fontSizeIcon,
  82. // when `transform: rotate()` is applied to icon's root element
  83. transition: `transform ${motionDurationSlow}`,
  84. // when `transform: rotate()` is applied to icon's child element
  85. svg: {
  86. transition: `transform ${motionDurationSlow}`
  87. }
  88. }),
  89. // >>>>> Text
  90. [`${componentCls}-header-text`]: {
  91. marginInlineEnd: 'auto'
  92. }
  93. }),
  94. [`${componentCls}-collapsible-header`]: {
  95. cursor: 'default',
  96. [`${componentCls}-header-text`]: {
  97. flex: 'none',
  98. cursor: 'pointer'
  99. },
  100. [`${componentCls}-expand-icon`]: {
  101. cursor: 'pointer'
  102. }
  103. },
  104. [`${componentCls}-collapsible-icon`]: {
  105. cursor: 'unset',
  106. [`${componentCls}-expand-icon`]: {
  107. cursor: 'pointer'
  108. }
  109. }
  110. },
  111. [`${componentCls}-content`]: {
  112. color: colorText,
  113. backgroundColor: contentBg,
  114. borderTop: borderBase,
  115. [`& > ${componentCls}-content-box`]: {
  116. padding: contentPadding
  117. },
  118. '&-hidden': {
  119. display: 'none'
  120. }
  121. },
  122. '&-small': {
  123. [`> ${componentCls}-item`]: {
  124. [`> ${componentCls}-header`]: {
  125. padding: collapseHeaderPaddingSM,
  126. paddingInlineStart: paddingXS,
  127. [`> ${componentCls}-expand-icon`]: {
  128. // Arrow offset
  129. marginInlineStart: token.calc(paddingSM).sub(paddingXS).equal()
  130. }
  131. },
  132. [`> ${componentCls}-content > ${componentCls}-content-box`]: {
  133. padding: paddingSM
  134. }
  135. }
  136. },
  137. '&-large': {
  138. [`> ${componentCls}-item`]: {
  139. fontSize: fontSizeLG,
  140. lineHeight: lineHeightLG,
  141. [`> ${componentCls}-header`]: {
  142. padding: collapseHeaderPaddingLG,
  143. paddingInlineStart: padding,
  144. [`> ${componentCls}-expand-icon`]: {
  145. height: fontHeightLG,
  146. // Arrow offset
  147. marginInlineStart: token.calc(paddingLG).sub(padding).equal()
  148. }
  149. },
  150. [`> ${componentCls}-content > ${componentCls}-content-box`]: {
  151. padding: paddingLG
  152. }
  153. }
  154. },
  155. [`${componentCls}-item:last-child`]: {
  156. borderBottom: 0,
  157. [`> ${componentCls}-content`]: {
  158. borderRadius: `0 0 ${unit(collapsePanelBorderRadius)} ${unit(collapsePanelBorderRadius)}`
  159. }
  160. },
  161. [`& ${componentCls}-item-disabled > ${componentCls}-header`]: {
  162. [`
  163. &,
  164. & > .arrow
  165. `]: {
  166. color: colorTextDisabled,
  167. cursor: 'not-allowed'
  168. }
  169. },
  170. // ========================== Icon Position ==========================
  171. [`&${componentCls}-icon-position-end`]: {
  172. [`& > ${componentCls}-item`]: {
  173. [`> ${componentCls}-header`]: {
  174. [`${componentCls}-expand-icon`]: {
  175. order: 1,
  176. paddingInlineEnd: 0,
  177. paddingInlineStart: marginSM
  178. }
  179. }
  180. }
  181. }
  182. })
  183. };
  184. };
  185. const genArrowStyle = token => {
  186. const {
  187. componentCls
  188. } = token;
  189. const fixedSelector = `> ${componentCls}-item > ${componentCls}-header ${componentCls}-arrow`;
  190. return {
  191. [`${componentCls}-rtl`]: {
  192. [fixedSelector]: {
  193. transform: `rotate(180deg)`
  194. }
  195. }
  196. };
  197. };
  198. const genBorderlessStyle = token => {
  199. const {
  200. componentCls,
  201. headerBg,
  202. borderlessContentPadding,
  203. borderlessContentBg,
  204. colorBorder
  205. } = token;
  206. return {
  207. [`${componentCls}-borderless`]: {
  208. backgroundColor: headerBg,
  209. border: 0,
  210. [`> ${componentCls}-item`]: {
  211. borderBottom: `1px solid ${colorBorder}`
  212. },
  213. [`
  214. > ${componentCls}-item:last-child,
  215. > ${componentCls}-item:last-child ${componentCls}-header
  216. `]: {
  217. borderRadius: 0
  218. },
  219. [`> ${componentCls}-item:last-child`]: {
  220. borderBottom: 0
  221. },
  222. [`> ${componentCls}-item > ${componentCls}-content`]: {
  223. backgroundColor: borderlessContentBg,
  224. borderTop: 0
  225. },
  226. [`> ${componentCls}-item > ${componentCls}-content > ${componentCls}-content-box`]: {
  227. padding: borderlessContentPadding
  228. }
  229. }
  230. };
  231. };
  232. const genGhostStyle = token => {
  233. const {
  234. componentCls,
  235. paddingSM
  236. } = token;
  237. return {
  238. [`${componentCls}-ghost`]: {
  239. backgroundColor: 'transparent',
  240. border: 0,
  241. [`> ${componentCls}-item`]: {
  242. borderBottom: 0,
  243. [`> ${componentCls}-content`]: {
  244. backgroundColor: 'transparent',
  245. border: 0,
  246. [`> ${componentCls}-content-box`]: {
  247. paddingBlock: paddingSM
  248. }
  249. }
  250. }
  251. }
  252. };
  253. };
  254. export const prepareComponentToken = token => ({
  255. headerPadding: `${token.paddingSM}px ${token.padding}px`,
  256. headerBg: token.colorFillAlter,
  257. contentPadding: `${token.padding}px 16px`,
  258. // Fixed Value
  259. contentBg: token.colorBgContainer,
  260. borderlessContentPadding: `${token.paddingXXS}px 16px ${token.padding}px`,
  261. borderlessContentBg: 'transparent'
  262. });
  263. export default genStyleHooks('Collapse', token => {
  264. const collapseToken = mergeToken(token, {
  265. collapseHeaderPaddingSM: `${unit(token.paddingXS)} ${unit(token.paddingSM)}`,
  266. collapseHeaderPaddingLG: `${unit(token.padding)} ${unit(token.paddingLG)}`,
  267. collapsePanelBorderRadius: token.borderRadiusLG
  268. });
  269. return [genBaseStyle(collapseToken), genBorderlessStyle(collapseToken), genGhostStyle(collapseToken), genArrowStyle(collapseToken), genCollapseMotion(collapseToken)];
  270. }, prepareComponentToken);