index.js 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
  2. import _extends from "@babel/runtime/helpers/esm/extends";
  3. import { resolveDirective as _resolveDirective, createVNode as _createVNode } from "vue";
  4. import { computed, defineComponent, ref } from 'vue';
  5. import classNames from '../_util/classNames';
  6. import RcSelect, { selectProps as vcSelectProps, Option, OptGroup } from '../vc-select';
  7. import getIcons from './utils/iconUtil';
  8. import PropTypes from '../_util/vue-types';
  9. import useConfigInject from '../config-provider/hooks/useConfigInject';
  10. import { DefaultRenderEmpty } from '../config-provider/renderEmpty';
  11. import omit from '../_util/omit';
  12. import { FormItemInputContext, useInjectFormItemContext } from '../form/FormItemContext';
  13. import { getTransitionDirection, getTransitionName } from '../_util/transition';
  14. import { initDefaultProps } from '../_util/props-util';
  15. import { getStatusClassNames, getMergedStatus } from '../_util/statusUtils';
  16. import { stringType, someType, functionType, booleanType } from '../_util/type';
  17. import { useCompactItemContext } from '../space/Compact';
  18. // CSSINJS
  19. import useStyle from './style';
  20. import { useInjectDisabled } from '../config-provider/DisabledContext';
  21. import devWarning from '../vc-util/devWarning';
  22. export const selectProps = () => _extends(_extends({}, omit(vcSelectProps(), ['inputIcon', 'mode', 'getInputElement', 'getRawInputElement', 'backfill'])), {
  23. value: someType([Array, Object, String, Number]),
  24. defaultValue: someType([Array, Object, String, Number]),
  25. notFoundContent: PropTypes.any,
  26. suffixIcon: PropTypes.any,
  27. itemIcon: PropTypes.any,
  28. size: stringType(),
  29. mode: stringType(),
  30. bordered: booleanType(true),
  31. transitionName: String,
  32. choiceTransitionName: stringType(''),
  33. popupClassName: String,
  34. /** @deprecated Please use `popupClassName` instead */
  35. dropdownClassName: String,
  36. placement: stringType(),
  37. status: stringType(),
  38. 'onUpdate:value': functionType()
  39. });
  40. const SECRET_COMBOBOX_MODE_DO_NOT_USE = 'SECRET_COMBOBOX_MODE_DO_NOT_USE';
  41. const Select = defineComponent({
  42. compatConfig: {
  43. MODE: 3
  44. },
  45. name: 'ASelect',
  46. Option,
  47. OptGroup,
  48. inheritAttrs: false,
  49. props: initDefaultProps(selectProps(), {
  50. listHeight: 256,
  51. listItemHeight: 24
  52. }),
  53. SECRET_COMBOBOX_MODE_DO_NOT_USE,
  54. slots: Object,
  55. setup(props, _ref) {
  56. let {
  57. attrs,
  58. emit,
  59. slots,
  60. expose
  61. } = _ref;
  62. const selectRef = ref();
  63. const formItemContext = useInjectFormItemContext();
  64. const formItemInputContext = FormItemInputContext.useInject();
  65. const mergedStatus = computed(() => getMergedStatus(formItemInputContext.status, props.status));
  66. const focus = () => {
  67. var _a;
  68. (_a = selectRef.value) === null || _a === void 0 ? void 0 : _a.focus();
  69. };
  70. const blur = () => {
  71. var _a;
  72. (_a = selectRef.value) === null || _a === void 0 ? void 0 : _a.blur();
  73. };
  74. const scrollTo = arg => {
  75. var _a;
  76. (_a = selectRef.value) === null || _a === void 0 ? void 0 : _a.scrollTo(arg);
  77. };
  78. const mode = computed(() => {
  79. const {
  80. mode
  81. } = props;
  82. if (mode === 'combobox') {
  83. return undefined;
  84. }
  85. if (mode === SECRET_COMBOBOX_MODE_DO_NOT_USE) {
  86. return 'combobox';
  87. }
  88. return mode;
  89. });
  90. // ====================== Warning ======================
  91. if (process.env.NODE_ENV !== 'production') {
  92. devWarning(!props.dropdownClassName, 'Select', '`dropdownClassName` is deprecated. Please use `popupClassName` instead.');
  93. }
  94. const {
  95. prefixCls,
  96. direction,
  97. configProvider,
  98. renderEmpty,
  99. size: contextSize,
  100. getPrefixCls,
  101. getPopupContainer,
  102. disabled,
  103. select
  104. } = useConfigInject('select', props);
  105. const {
  106. compactSize,
  107. compactItemClassnames
  108. } = useCompactItemContext(prefixCls, direction);
  109. const mergedSize = computed(() => compactSize.value || contextSize.value);
  110. const contextDisabled = useInjectDisabled();
  111. const mergedDisabled = computed(() => {
  112. var _a;
  113. return (_a = disabled.value) !== null && _a !== void 0 ? _a : contextDisabled.value;
  114. });
  115. // style
  116. const [wrapSSR, hashId] = useStyle(prefixCls);
  117. const rootPrefixCls = computed(() => getPrefixCls());
  118. // ===================== Placement =====================
  119. const placement = computed(() => {
  120. if (props.placement !== undefined) {
  121. return props.placement;
  122. }
  123. return direction.value === 'rtl' ? 'bottomRight' : 'bottomLeft';
  124. });
  125. const transitionName = computed(() => getTransitionName(rootPrefixCls.value, getTransitionDirection(placement.value), props.transitionName));
  126. const mergedClassName = computed(() => classNames({
  127. [`${prefixCls.value}-lg`]: mergedSize.value === 'large',
  128. [`${prefixCls.value}-sm`]: mergedSize.value === 'small',
  129. [`${prefixCls.value}-rtl`]: direction.value === 'rtl',
  130. [`${prefixCls.value}-borderless`]: !props.bordered,
  131. [`${prefixCls.value}-in-form-item`]: formItemInputContext.isFormItemInput
  132. }, getStatusClassNames(prefixCls.value, mergedStatus.value, formItemInputContext.hasFeedback), compactItemClassnames.value, hashId.value));
  133. const triggerChange = function () {
  134. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  135. args[_key] = arguments[_key];
  136. }
  137. emit('update:value', args[0]);
  138. emit('change', ...args);
  139. formItemContext.onFieldChange();
  140. };
  141. const handleBlur = e => {
  142. emit('blur', e);
  143. formItemContext.onFieldBlur();
  144. };
  145. expose({
  146. blur,
  147. focus,
  148. scrollTo
  149. });
  150. const isMultiple = computed(() => mode.value === 'multiple' || mode.value === 'tags');
  151. const mergedShowArrow = computed(() => props.showArrow !== undefined ? props.showArrow : props.loading || !(isMultiple.value || mode.value === 'combobox'));
  152. return () => {
  153. var _a, _b, _c, _d;
  154. const {
  155. notFoundContent,
  156. listHeight = 256,
  157. listItemHeight = 24,
  158. popupClassName,
  159. dropdownClassName,
  160. virtual,
  161. dropdownMatchSelectWidth,
  162. id = formItemContext.id.value,
  163. placeholder = (_a = slots.placeholder) === null || _a === void 0 ? void 0 : _a.call(slots),
  164. showArrow
  165. } = props;
  166. const {
  167. hasFeedback,
  168. feedbackIcon
  169. } = formItemInputContext;
  170. const {} = configProvider;
  171. // ===================== Empty =====================
  172. let mergedNotFound;
  173. if (notFoundContent !== undefined) {
  174. mergedNotFound = notFoundContent;
  175. } else if (slots.notFoundContent) {
  176. mergedNotFound = slots.notFoundContent();
  177. } else if (mode.value === 'combobox') {
  178. mergedNotFound = null;
  179. } else {
  180. mergedNotFound = (renderEmpty === null || renderEmpty === void 0 ? void 0 : renderEmpty('Select')) || _createVNode(DefaultRenderEmpty, {
  181. "componentName": "Select"
  182. }, null);
  183. }
  184. // ===================== Icons =====================
  185. const {
  186. suffixIcon,
  187. itemIcon,
  188. removeIcon,
  189. clearIcon
  190. } = getIcons(_extends(_extends({}, props), {
  191. multiple: isMultiple.value,
  192. prefixCls: prefixCls.value,
  193. hasFeedback,
  194. feedbackIcon,
  195. showArrow: mergedShowArrow.value
  196. }), slots);
  197. const selectProps = omit(props, ['prefixCls', 'suffixIcon', 'itemIcon', 'removeIcon', 'clearIcon', 'size', 'bordered', 'status']);
  198. const rcSelectRtlDropdownClassName = classNames(popupClassName || dropdownClassName, {
  199. [`${prefixCls.value}-dropdown-${direction.value}`]: direction.value === 'rtl'
  200. }, hashId.value);
  201. return wrapSSR(_createVNode(RcSelect, _objectSpread(_objectSpread(_objectSpread({
  202. "ref": selectRef,
  203. "virtual": virtual,
  204. "dropdownMatchSelectWidth": dropdownMatchSelectWidth
  205. }, selectProps), attrs), {}, {
  206. "showSearch": (_b = props.showSearch) !== null && _b !== void 0 ? _b : (_c = select === null || select === void 0 ? void 0 : select.value) === null || _c === void 0 ? void 0 : _c.showSearch,
  207. "placeholder": placeholder,
  208. "listHeight": listHeight,
  209. "listItemHeight": listItemHeight,
  210. "mode": mode.value,
  211. "prefixCls": prefixCls.value,
  212. "direction": direction.value,
  213. "inputIcon": suffixIcon,
  214. "menuItemSelectedIcon": itemIcon,
  215. "removeIcon": removeIcon,
  216. "clearIcon": clearIcon,
  217. "notFoundContent": mergedNotFound,
  218. "class": [mergedClassName.value, attrs.class],
  219. "getPopupContainer": getPopupContainer === null || getPopupContainer === void 0 ? void 0 : getPopupContainer.value,
  220. "dropdownClassName": rcSelectRtlDropdownClassName,
  221. "onChange": triggerChange,
  222. "onBlur": handleBlur,
  223. "id": id,
  224. "dropdownRender": selectProps.dropdownRender || slots.dropdownRender,
  225. "transitionName": transitionName.value,
  226. "children": (_d = slots.default) === null || _d === void 0 ? void 0 : _d.call(slots),
  227. "tagRender": props.tagRender || slots.tagRender,
  228. "optionLabelRender": slots.optionLabel,
  229. "maxTagPlaceholder": props.maxTagPlaceholder || slots.maxTagPlaceholder,
  230. "showArrow": hasFeedback || showArrow,
  231. "disabled": mergedDisabled.value
  232. }), {
  233. option: slots.option
  234. }));
  235. };
  236. }
  237. });
  238. /* istanbul ignore next */
  239. Select.install = function (app) {
  240. app.component(Select.name, Select);
  241. app.component(Select.Option.displayName, Select.Option);
  242. app.component(Select.OptGroup.displayName, Select.OptGroup);
  243. return app;
  244. };
  245. export const SelectOption = Select.Option;
  246. export const SelectOptGroup = Select.OptGroup;
  247. export default Select;