index.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  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, ref, defineComponent } from 'vue';
  5. import VcTreeSelect, { TreeNode, SHOW_ALL, SHOW_PARENT, SHOW_CHILD, treeSelectProps as vcTreeSelectProps } from '../vc-tree-select';
  6. import classNames from '../_util/classNames';
  7. import initDefaultProps from '../_util/props-util/initDefaultProps';
  8. import omit from '../_util/omit';
  9. import PropTypes from '../_util/vue-types';
  10. import useConfigInject from '../config-provider/hooks/useConfigInject';
  11. import devWarning from '../vc-util/devWarning';
  12. import getIcons from '../select/utils/iconUtil';
  13. import renderSwitcherIcon from '../tree/utils/iconUtil';
  14. import { warning } from '../vc-util/warning';
  15. import { flattenChildren } from '../_util/props-util';
  16. import { FormItemInputContext, useInjectFormItemContext } from '../form/FormItemContext';
  17. import { getTransitionDirection } from '../_util/transition';
  18. import { getStatusClassNames, getMergedStatus } from '../_util/statusUtils';
  19. import { booleanType, stringType, objectType, someType, functionType } from '../_util/type';
  20. // CSSINJS
  21. import useSelectStyle from '../select/style';
  22. import useStyle from './style';
  23. import { useCompactItemContext } from '../space/Compact';
  24. import { useInjectDisabled } from '../config-provider/DisabledContext';
  25. const getTransitionName = (rootPrefixCls, motion, transitionName) => {
  26. if (transitionName !== undefined) {
  27. return transitionName;
  28. }
  29. return `${rootPrefixCls}-${motion}`;
  30. };
  31. export function treeSelectProps() {
  32. return _extends(_extends({}, omit(vcTreeSelectProps(), ['showTreeIcon', 'treeMotion', 'inputIcon', 'getInputElement', 'treeLine', 'customSlots'])), {
  33. suffixIcon: PropTypes.any,
  34. size: stringType(),
  35. bordered: booleanType(),
  36. treeLine: someType([Boolean, Object]),
  37. replaceFields: objectType(),
  38. placement: stringType(),
  39. status: stringType(),
  40. popupClassName: String,
  41. /** @deprecated Please use `popupClassName` instead */
  42. dropdownClassName: String,
  43. 'onUpdate:value': functionType(),
  44. 'onUpdate:treeExpandedKeys': functionType(),
  45. 'onUpdate:searchValue': functionType()
  46. });
  47. }
  48. const TreeSelect = defineComponent({
  49. compatConfig: {
  50. MODE: 3
  51. },
  52. name: 'ATreeSelect',
  53. inheritAttrs: false,
  54. props: initDefaultProps(treeSelectProps(), {
  55. choiceTransitionName: '',
  56. listHeight: 256,
  57. treeIcon: false,
  58. listItemHeight: 26,
  59. bordered: true
  60. }),
  61. slots: Object,
  62. setup(props, _ref) {
  63. let {
  64. attrs,
  65. slots,
  66. expose,
  67. emit
  68. } = _ref;
  69. warning(!(props.treeData === undefined && slots.default), '`children` of TreeSelect is deprecated. Please use `treeData` instead.');
  70. devWarning(props.multiple !== false || !props.treeCheckable, 'TreeSelect', '`multiple` will always be `true` when `treeCheckable` is true');
  71. devWarning(props.replaceFields === undefined, 'TreeSelect', '`replaceFields` is deprecated, please use fieldNames instead');
  72. devWarning(!props.dropdownClassName, 'TreeSelect', '`dropdownClassName` is deprecated. Please use `popupClassName` instead.');
  73. const formItemContext = useInjectFormItemContext();
  74. const formItemInputContext = FormItemInputContext.useInject();
  75. const mergedStatus = computed(() => getMergedStatus(formItemInputContext.status, props.status));
  76. const {
  77. prefixCls,
  78. renderEmpty,
  79. direction,
  80. virtual,
  81. dropdownMatchSelectWidth,
  82. size: contextSize,
  83. getPopupContainer,
  84. getPrefixCls,
  85. disabled
  86. } = useConfigInject('select', props);
  87. const {
  88. compactSize,
  89. compactItemClassnames
  90. } = useCompactItemContext(prefixCls, direction);
  91. const mergedSize = computed(() => compactSize.value || contextSize.value);
  92. const contextDisabled = useInjectDisabled();
  93. const mergedDisabled = computed(() => {
  94. var _a;
  95. return (_a = disabled.value) !== null && _a !== void 0 ? _a : contextDisabled.value;
  96. });
  97. const rootPrefixCls = computed(() => getPrefixCls());
  98. // ===================== Placement =====================
  99. const placement = computed(() => {
  100. if (props.placement !== undefined) {
  101. return props.placement;
  102. }
  103. return direction.value === 'rtl' ? 'bottomRight' : 'bottomLeft';
  104. });
  105. const transitionName = computed(() => getTransitionName(rootPrefixCls.value, getTransitionDirection(placement.value), props.transitionName));
  106. const choiceTransitionName = computed(() => getTransitionName(rootPrefixCls.value, '', props.choiceTransitionName));
  107. const treePrefixCls = computed(() => getPrefixCls('select-tree', props.prefixCls));
  108. const treeSelectPrefixCls = computed(() => getPrefixCls('tree-select', props.prefixCls));
  109. // style
  110. const [wrapSelectSSR, hashId] = useSelectStyle(prefixCls);
  111. const [wrapTreeSelectSSR] = useStyle(treeSelectPrefixCls, treePrefixCls);
  112. const mergedDropdownClassName = computed(() => classNames(props.popupClassName || props.dropdownClassName, `${treeSelectPrefixCls.value}-dropdown`, {
  113. [`${treeSelectPrefixCls.value}-dropdown-rtl`]: direction.value === 'rtl'
  114. }, hashId.value));
  115. const isMultiple = computed(() => !!(props.treeCheckable || props.multiple));
  116. const mergedShowArrow = computed(() => props.showArrow !== undefined ? props.showArrow : props.loading || !isMultiple.value);
  117. const treeSelectRef = ref();
  118. expose({
  119. focus() {
  120. var _a, _b;
  121. (_b = (_a = treeSelectRef.value).focus) === null || _b === void 0 ? void 0 : _b.call(_a);
  122. },
  123. blur() {
  124. var _a, _b;
  125. (_b = (_a = treeSelectRef.value).blur) === null || _b === void 0 ? void 0 : _b.call(_a);
  126. }
  127. });
  128. const handleChange = function () {
  129. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  130. args[_key] = arguments[_key];
  131. }
  132. emit('update:value', args[0]);
  133. emit('change', ...args);
  134. formItemContext.onFieldChange();
  135. };
  136. const handleTreeExpand = keys => {
  137. emit('update:treeExpandedKeys', keys);
  138. emit('treeExpand', keys);
  139. };
  140. const handleSearch = value => {
  141. emit('update:searchValue', value);
  142. emit('search', value);
  143. };
  144. const handleBlur = e => {
  145. emit('blur', e);
  146. formItemContext.onFieldBlur();
  147. };
  148. return () => {
  149. var _a, _b, _c;
  150. const {
  151. notFoundContent = (_a = slots.notFoundContent) === null || _a === void 0 ? void 0 : _a.call(slots),
  152. prefixCls: customizePrefixCls,
  153. bordered,
  154. listHeight,
  155. listItemHeight,
  156. multiple,
  157. treeIcon,
  158. treeLine,
  159. showArrow,
  160. switcherIcon = (_b = slots.switcherIcon) === null || _b === void 0 ? void 0 : _b.call(slots),
  161. fieldNames = props.replaceFields,
  162. id = formItemContext.id.value,
  163. placeholder = (_c = slots.placeholder) === null || _c === void 0 ? void 0 : _c.call(slots)
  164. } = props;
  165. const {
  166. isFormItemInput,
  167. hasFeedback,
  168. feedbackIcon
  169. } = formItemInputContext;
  170. // ===================== Icons =====================
  171. const {
  172. suffixIcon,
  173. removeIcon,
  174. clearIcon
  175. } = getIcons(_extends(_extends({}, props), {
  176. multiple: isMultiple.value,
  177. showArrow: mergedShowArrow.value,
  178. hasFeedback,
  179. feedbackIcon,
  180. prefixCls: prefixCls.value
  181. }), slots);
  182. // ===================== Empty =====================
  183. let mergedNotFound;
  184. if (notFoundContent !== undefined) {
  185. mergedNotFound = notFoundContent;
  186. } else {
  187. mergedNotFound = renderEmpty('Select');
  188. }
  189. // ==================== Render =====================
  190. const selectProps = omit(props, ['suffixIcon', 'itemIcon', 'removeIcon', 'clearIcon', 'switcherIcon', 'bordered', 'status', 'onUpdate:value', 'onUpdate:treeExpandedKeys', 'onUpdate:searchValue']);
  191. const mergedClassName = classNames(!customizePrefixCls && treeSelectPrefixCls.value, {
  192. [`${prefixCls.value}-lg`]: mergedSize.value === 'large',
  193. [`${prefixCls.value}-sm`]: mergedSize.value === 'small',
  194. [`${prefixCls.value}-rtl`]: direction.value === 'rtl',
  195. [`${prefixCls.value}-borderless`]: !bordered,
  196. [`${prefixCls.value}-in-form-item`]: isFormItemInput
  197. }, getStatusClassNames(prefixCls.value, mergedStatus.value, hasFeedback), compactItemClassnames.value, attrs.class, hashId.value);
  198. const otherProps = {};
  199. if (props.treeData === undefined && slots.default) {
  200. otherProps.children = flattenChildren(slots.default());
  201. }
  202. return wrapSelectSSR(wrapTreeSelectSSR(_createVNode(VcTreeSelect, _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, attrs), selectProps), {}, {
  203. "disabled": mergedDisabled.value,
  204. "virtual": virtual.value,
  205. "dropdownMatchSelectWidth": dropdownMatchSelectWidth.value,
  206. "id": id,
  207. "fieldNames": fieldNames,
  208. "ref": treeSelectRef,
  209. "prefixCls": prefixCls.value,
  210. "class": mergedClassName,
  211. "listHeight": listHeight,
  212. "listItemHeight": listItemHeight,
  213. "treeLine": !!treeLine,
  214. "inputIcon": suffixIcon,
  215. "multiple": multiple,
  216. "removeIcon": removeIcon,
  217. "clearIcon": clearIcon,
  218. "switcherIcon": nodeProps => renderSwitcherIcon(treePrefixCls.value, switcherIcon, nodeProps, slots.leafIcon, treeLine),
  219. "showTreeIcon": treeIcon,
  220. "notFoundContent": mergedNotFound,
  221. "getPopupContainer": getPopupContainer === null || getPopupContainer === void 0 ? void 0 : getPopupContainer.value,
  222. "treeMotion": null,
  223. "dropdownClassName": mergedDropdownClassName.value,
  224. "choiceTransitionName": choiceTransitionName.value,
  225. "onChange": handleChange,
  226. "onBlur": handleBlur,
  227. "onSearch": handleSearch,
  228. "onTreeExpand": handleTreeExpand
  229. }, otherProps), {}, {
  230. "transitionName": transitionName.value,
  231. "customSlots": _extends(_extends({}, slots), {
  232. treeCheckable: () => _createVNode("span", {
  233. "class": `${prefixCls.value}-tree-checkbox-inner`
  234. }, null)
  235. }),
  236. "maxTagPlaceholder": props.maxTagPlaceholder || slots.maxTagPlaceholder,
  237. "placement": placement.value,
  238. "showArrow": hasFeedback || showArrow,
  239. "placeholder": placeholder
  240. }), _extends(_extends({}, slots), {
  241. treeCheckable: () => _createVNode("span", {
  242. "class": `${prefixCls.value}-tree-checkbox-inner`
  243. }, null)
  244. }))));
  245. };
  246. }
  247. });
  248. /* istanbul ignore next */
  249. export const TreeSelectNode = TreeNode;
  250. export default _extends(TreeSelect, {
  251. TreeNode,
  252. SHOW_ALL: SHOW_ALL,
  253. SHOW_PARENT: SHOW_PARENT,
  254. SHOW_CHILD: SHOW_CHILD,
  255. install: app => {
  256. app.component(TreeSelect.name, TreeSelect);
  257. app.component(TreeSelectNode.displayName, TreeSelectNode);
  258. return app;
  259. }
  260. });