index.js 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. import _extends from "@babel/runtime/helpers/esm/extends";
  2. import { genComponentStyleHook, mergeToken } from '../../theme/internal';
  3. import genDropdownStyle from './dropdown';
  4. import genMultipleStyle from './multiple';
  5. import genSingleStyle from './single';
  6. import { resetComponent, resetIcon, textEllipsis } from '../../style';
  7. import { genCompactItemStyle } from '../../style/compact-item';
  8. // ============================= Selector =============================
  9. const genSelectorStyle = token => {
  10. const {
  11. componentCls
  12. } = token;
  13. return {
  14. position: 'relative',
  15. backgroundColor: token.colorBgContainer,
  16. border: `${token.lineWidth}px ${token.lineType} ${token.colorBorder}`,
  17. transition: `all ${token.motionDurationMid} ${token.motionEaseInOut}`,
  18. input: {
  19. cursor: 'pointer'
  20. },
  21. [`${componentCls}-show-search&`]: {
  22. cursor: 'text',
  23. input: {
  24. cursor: 'auto',
  25. color: 'inherit'
  26. }
  27. },
  28. [`${componentCls}-disabled&`]: {
  29. color: token.colorTextDisabled,
  30. background: token.colorBgContainerDisabled,
  31. cursor: 'not-allowed',
  32. [`${componentCls}-multiple&`]: {
  33. background: token.colorBgContainerDisabled
  34. },
  35. input: {
  36. cursor: 'not-allowed'
  37. }
  38. }
  39. };
  40. };
  41. // ============================== Status ==============================
  42. const genStatusStyle = function (rootSelectCls, token) {
  43. let overwriteDefaultBorder = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
  44. const {
  45. componentCls,
  46. borderHoverColor,
  47. outlineColor,
  48. antCls
  49. } = token;
  50. const overwriteStyle = overwriteDefaultBorder ? {
  51. [`${componentCls}-selector`]: {
  52. borderColor: borderHoverColor
  53. }
  54. } : {};
  55. return {
  56. [rootSelectCls]: {
  57. [`&:not(${componentCls}-disabled):not(${componentCls}-customize-input):not(${antCls}-pagination-size-changer)`]: _extends(_extends({}, overwriteStyle), {
  58. [`${componentCls}-focused& ${componentCls}-selector`]: {
  59. borderColor: borderHoverColor,
  60. boxShadow: `0 0 0 ${token.controlOutlineWidth}px ${outlineColor}`,
  61. borderInlineEndWidth: `${token.controlLineWidth}px !important`,
  62. outline: 0
  63. },
  64. [`&:hover ${componentCls}-selector`]: {
  65. borderColor: borderHoverColor,
  66. borderInlineEndWidth: `${token.controlLineWidth}px !important`
  67. }
  68. })
  69. }
  70. };
  71. };
  72. // ============================== Styles ==============================
  73. // /* Reset search input style */
  74. const getSearchInputWithoutBorderStyle = token => {
  75. const {
  76. componentCls
  77. } = token;
  78. return {
  79. [`${componentCls}-selection-search-input`]: {
  80. margin: 0,
  81. padding: 0,
  82. background: 'transparent',
  83. border: 'none',
  84. outline: 'none',
  85. appearance: 'none',
  86. '&::-webkit-search-cancel-button': {
  87. display: 'none',
  88. '-webkit-appearance': 'none'
  89. }
  90. }
  91. };
  92. };
  93. // =============================== Base ===============================
  94. const genBaseStyle = token => {
  95. const {
  96. componentCls,
  97. inputPaddingHorizontalBase,
  98. iconCls
  99. } = token;
  100. return {
  101. [componentCls]: _extends(_extends({}, resetComponent(token)), {
  102. position: 'relative',
  103. display: 'inline-block',
  104. cursor: 'pointer',
  105. [`&:not(${componentCls}-customize-input) ${componentCls}-selector`]: _extends(_extends({}, genSelectorStyle(token)), getSearchInputWithoutBorderStyle(token)),
  106. // [`&:not(&-disabled):hover ${selectCls}-selector`]: {
  107. // ...genHoverStyle(token),
  108. // },
  109. // ======================== Selection ========================
  110. [`${componentCls}-selection-item`]: _extends({
  111. flex: 1,
  112. fontWeight: 'normal'
  113. }, textEllipsis),
  114. // ======================= Placeholder =======================
  115. [`${componentCls}-selection-placeholder`]: _extends(_extends({}, textEllipsis), {
  116. flex: 1,
  117. color: token.colorTextPlaceholder,
  118. pointerEvents: 'none'
  119. }),
  120. // ========================== Arrow ==========================
  121. [`${componentCls}-arrow`]: _extends(_extends({}, resetIcon()), {
  122. position: 'absolute',
  123. top: '50%',
  124. insetInlineStart: 'auto',
  125. insetInlineEnd: inputPaddingHorizontalBase,
  126. height: token.fontSizeIcon,
  127. marginTop: -token.fontSizeIcon / 2,
  128. color: token.colorTextQuaternary,
  129. fontSize: token.fontSizeIcon,
  130. lineHeight: 1,
  131. textAlign: 'center',
  132. pointerEvents: 'none',
  133. display: 'flex',
  134. alignItems: 'center',
  135. [iconCls]: {
  136. verticalAlign: 'top',
  137. transition: `transform ${token.motionDurationSlow}`,
  138. '> svg': {
  139. verticalAlign: 'top'
  140. },
  141. [`&:not(${componentCls}-suffix)`]: {
  142. pointerEvents: 'auto'
  143. }
  144. },
  145. [`${componentCls}-disabled &`]: {
  146. cursor: 'not-allowed'
  147. },
  148. '> *:not(:last-child)': {
  149. marginInlineEnd: 8 // FIXME: magic
  150. }
  151. }),
  152. // ========================== Clear ==========================
  153. [`${componentCls}-clear`]: {
  154. position: 'absolute',
  155. top: '50%',
  156. insetInlineStart: 'auto',
  157. insetInlineEnd: inputPaddingHorizontalBase,
  158. zIndex: 1,
  159. display: 'inline-block',
  160. width: token.fontSizeIcon,
  161. height: token.fontSizeIcon,
  162. marginTop: -token.fontSizeIcon / 2,
  163. color: token.colorTextQuaternary,
  164. fontSize: token.fontSizeIcon,
  165. fontStyle: 'normal',
  166. lineHeight: 1,
  167. textAlign: 'center',
  168. textTransform: 'none',
  169. background: token.colorBgContainer,
  170. cursor: 'pointer',
  171. opacity: 0,
  172. transition: `color ${token.motionDurationMid} ease, opacity ${token.motionDurationSlow} ease`,
  173. textRendering: 'auto',
  174. '&:before': {
  175. display: 'block'
  176. },
  177. '&:hover': {
  178. color: token.colorTextTertiary
  179. }
  180. },
  181. '&:hover': {
  182. [`${componentCls}-clear`]: {
  183. opacity: 1
  184. }
  185. }
  186. }),
  187. // ========================= Feedback ==========================
  188. [`${componentCls}-has-feedback`]: {
  189. [`${componentCls}-clear`]: {
  190. insetInlineEnd: inputPaddingHorizontalBase + token.fontSize + token.paddingXXS
  191. }
  192. }
  193. };
  194. };
  195. // ============================== Styles ==============================
  196. const genSelectStyle = token => {
  197. const {
  198. componentCls
  199. } = token;
  200. return [{
  201. [componentCls]: {
  202. // ==================== BorderLess ====================
  203. [`&-borderless ${componentCls}-selector`]: {
  204. backgroundColor: `transparent !important`,
  205. borderColor: `transparent !important`,
  206. boxShadow: `none !important`
  207. },
  208. // ==================== In Form ====================
  209. [`&${componentCls}-in-form-item`]: {
  210. width: '100%'
  211. }
  212. }
  213. },
  214. // =====================================================
  215. // == LTR ==
  216. // =====================================================
  217. // Base
  218. genBaseStyle(token),
  219. // Single
  220. genSingleStyle(token),
  221. // Multiple
  222. genMultipleStyle(token),
  223. // Dropdown
  224. genDropdownStyle(token),
  225. // =====================================================
  226. // == RTL ==
  227. // =====================================================
  228. {
  229. [`${componentCls}-rtl`]: {
  230. direction: 'rtl'
  231. }
  232. },
  233. // =====================================================
  234. // == Status ==
  235. // =====================================================
  236. genStatusStyle(componentCls, mergeToken(token, {
  237. borderHoverColor: token.colorPrimaryHover,
  238. outlineColor: token.controlOutline
  239. })), genStatusStyle(`${componentCls}-status-error`, mergeToken(token, {
  240. borderHoverColor: token.colorErrorHover,
  241. outlineColor: token.colorErrorOutline
  242. }), true), genStatusStyle(`${componentCls}-status-warning`, mergeToken(token, {
  243. borderHoverColor: token.colorWarningHover,
  244. outlineColor: token.colorWarningOutline
  245. }), true),
  246. // =====================================================
  247. // == Space Compact ==
  248. // =====================================================
  249. genCompactItemStyle(token, {
  250. borderElCls: `${componentCls}-selector`,
  251. focusElCls: `${componentCls}-focused`
  252. })];
  253. };
  254. // ============================== Export ==============================
  255. export default genComponentStyleHook('Select', (token, _ref) => {
  256. let {
  257. rootPrefixCls
  258. } = _ref;
  259. const selectToken = mergeToken(token, {
  260. rootPrefixCls,
  261. inputPaddingHorizontalBase: token.paddingSM - 1
  262. });
  263. return [genSelectStyle(selectToken)];
  264. }, token => ({
  265. zIndexPopup: token.zIndexPopupBase + 50
  266. }));