MultipleSelector.js 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
  2. import { Fragment as _Fragment, createTextVNode as _createTextVNode, createVNode as _createVNode } from "vue";
  3. import TransBtn from '../TransBtn';
  4. import Input from './Input';
  5. import { computed, defineComponent, onMounted, ref, watch } from 'vue';
  6. import classNames from '../../_util/classNames';
  7. import pickAttrs from '../../_util/pickAttrs';
  8. import PropTypes from '../../_util/vue-types';
  9. import Overflow from '../../vc-overflow';
  10. import useInjectLegacySelectContext from '../../vc-tree-select/LegacyContext';
  11. var props = {
  12. id: String,
  13. prefixCls: String,
  14. values: PropTypes.array,
  15. open: {
  16. type: Boolean,
  17. default: undefined
  18. },
  19. searchValue: String,
  20. inputRef: PropTypes.any,
  21. placeholder: PropTypes.any,
  22. disabled: {
  23. type: Boolean,
  24. default: undefined
  25. },
  26. mode: String,
  27. showSearch: {
  28. type: Boolean,
  29. default: undefined
  30. },
  31. autofocus: {
  32. type: Boolean,
  33. default: undefined
  34. },
  35. autocomplete: String,
  36. activeDescendantId: String,
  37. tabindex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  38. removeIcon: PropTypes.any,
  39. choiceTransitionName: String,
  40. maxTagCount: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  41. maxTagTextLength: Number,
  42. maxTagPlaceholder: PropTypes.any.def(function () {
  43. return function (omittedValues) {
  44. return "+ ".concat(omittedValues.length, " ...");
  45. };
  46. }),
  47. tagRender: Function,
  48. onToggleOpen: {
  49. type: Function
  50. },
  51. onRemove: Function,
  52. onInputChange: Function,
  53. onInputPaste: Function,
  54. onInputKeyDown: Function,
  55. onInputMouseDown: Function,
  56. onInputCompositionStart: Function,
  57. onInputCompositionEnd: Function
  58. };
  59. var onPreventMouseDown = function onPreventMouseDown(event) {
  60. event.preventDefault();
  61. event.stopPropagation();
  62. };
  63. var SelectSelector = defineComponent({
  64. name: 'MultipleSelectSelector',
  65. inheritAttrs: false,
  66. props: props,
  67. setup: function setup(props) {
  68. var measureRef = ref();
  69. var inputWidth = ref(0);
  70. var focused = ref(false);
  71. var legacyTreeSelectContext = useInjectLegacySelectContext();
  72. var selectionPrefixCls = computed(function () {
  73. return "".concat(props.prefixCls, "-selection");
  74. });
  75. // ===================== Search ======================
  76. var inputValue = computed(function () {
  77. return props.open || props.mode === 'tags' ? props.searchValue : '';
  78. });
  79. var inputEditable = computed(function () {
  80. return props.mode === 'tags' || props.showSearch && (props.open || focused.value);
  81. });
  82. // We measure width and set to the input immediately
  83. onMounted(function () {
  84. watch(inputValue, function () {
  85. inputWidth.value = measureRef.value.scrollWidth;
  86. }, {
  87. flush: 'post',
  88. immediate: true
  89. });
  90. });
  91. // ===================== Render ======================
  92. // >>> Render Selector Node. Includes Item & Rest
  93. function defaultRenderSelector(title, content, itemDisabled, closable, onClose) {
  94. return _createVNode("span", {
  95. "class": classNames("".concat(selectionPrefixCls.value, "-item"), _defineProperty({}, "".concat(selectionPrefixCls.value, "-item-disabled"), itemDisabled)),
  96. "title": typeof title === 'string' || typeof title === 'number' ? title.toString() : undefined
  97. }, [_createVNode("span", {
  98. "class": "".concat(selectionPrefixCls.value, "-item-content")
  99. }, [content]), closable && _createVNode(TransBtn, {
  100. "class": "".concat(selectionPrefixCls.value, "-item-remove"),
  101. "onMousedown": onPreventMouseDown,
  102. "onClick": onClose,
  103. "customizeIcon": props.removeIcon
  104. }, {
  105. default: function _default() {
  106. return [_createTextVNode("\xD7")];
  107. }
  108. })]);
  109. }
  110. function customizeRenderSelector(value, content, itemDisabled, closable, onClose, option) {
  111. var onMouseDown = function onMouseDown(e) {
  112. onPreventMouseDown(e);
  113. props.onToggleOpen(!open);
  114. };
  115. var originData = option;
  116. // For TreeSelect
  117. if (legacyTreeSelectContext.keyEntities) {
  118. var _legacyTreeSelectCont;
  119. originData = ((_legacyTreeSelectCont = legacyTreeSelectContext.keyEntities[value]) === null || _legacyTreeSelectCont === void 0 ? void 0 : _legacyTreeSelectCont.node) || {};
  120. }
  121. return _createVNode("span", {
  122. "key": value,
  123. "onMousedown": onMouseDown
  124. }, [props.tagRender({
  125. label: content,
  126. value: value,
  127. disabled: itemDisabled,
  128. closable: closable,
  129. onClose: onClose,
  130. option: originData
  131. })]);
  132. }
  133. function renderItem(valueItem) {
  134. var itemDisabled = valueItem.disabled,
  135. label = valueItem.label,
  136. value = valueItem.value,
  137. option = valueItem.option;
  138. var closable = !props.disabled && !itemDisabled;
  139. var displayLabel = label;
  140. if (typeof props.maxTagTextLength === 'number') {
  141. if (typeof label === 'string' || typeof label === 'number') {
  142. var strLabel = String(displayLabel);
  143. if (strLabel.length > props.maxTagTextLength) {
  144. displayLabel = "".concat(strLabel.slice(0, props.maxTagTextLength), "...");
  145. }
  146. }
  147. }
  148. var onClose = function onClose(event) {
  149. var _props$onRemove;
  150. if (event) event.stopPropagation();
  151. (_props$onRemove = props.onRemove) === null || _props$onRemove === void 0 ? void 0 : _props$onRemove.call(props, valueItem);
  152. };
  153. return typeof props.tagRender === 'function' ? customizeRenderSelector(value, displayLabel, itemDisabled, closable, onClose, option) : defaultRenderSelector(label, displayLabel, itemDisabled, closable, onClose);
  154. }
  155. function renderRest(omittedValues) {
  156. var _props$maxTagPlacehol = props.maxTagPlaceholder,
  157. maxTagPlaceholder = _props$maxTagPlacehol === void 0 ? function (omittedValues) {
  158. return "+ ".concat(omittedValues.length, " ...");
  159. } : _props$maxTagPlacehol;
  160. var content = typeof maxTagPlaceholder === 'function' ? maxTagPlaceholder(omittedValues) : maxTagPlaceholder;
  161. return defaultRenderSelector(content, content, false);
  162. }
  163. return function () {
  164. var id = props.id,
  165. prefixCls = props.prefixCls,
  166. values = props.values,
  167. open = props.open,
  168. inputRef = props.inputRef,
  169. placeholder = props.placeholder,
  170. disabled = props.disabled,
  171. autofocus = props.autofocus,
  172. autocomplete = props.autocomplete,
  173. activeDescendantId = props.activeDescendantId,
  174. tabindex = props.tabindex,
  175. onInputChange = props.onInputChange,
  176. onInputPaste = props.onInputPaste,
  177. onInputKeyDown = props.onInputKeyDown,
  178. onInputMouseDown = props.onInputMouseDown,
  179. onInputCompositionStart = props.onInputCompositionStart,
  180. onInputCompositionEnd = props.onInputCompositionEnd;
  181. // >>> Input Node
  182. var inputNode = _createVNode("div", {
  183. "class": "".concat(selectionPrefixCls.value, "-search"),
  184. "style": {
  185. width: inputWidth.value + 'px'
  186. },
  187. "key": "input"
  188. }, [_createVNode(Input, {
  189. "inputRef": inputRef,
  190. "open": open,
  191. "prefixCls": prefixCls,
  192. "id": id,
  193. "inputElement": null,
  194. "disabled": disabled,
  195. "autofocus": autofocus,
  196. "autocomplete": autocomplete,
  197. "editable": inputEditable.value,
  198. "activeDescendantId": activeDescendantId,
  199. "value": inputValue.value,
  200. "onKeydown": onInputKeyDown,
  201. "onMousedown": onInputMouseDown,
  202. "onChange": onInputChange,
  203. "onPaste": onInputPaste,
  204. "onCompositionstart": onInputCompositionStart,
  205. "onCompositionend": onInputCompositionEnd,
  206. "tabindex": tabindex,
  207. "attrs": pickAttrs(props, true),
  208. "onFocus": function onFocus() {
  209. return focused.value = true;
  210. },
  211. "onBlur": function onBlur() {
  212. return focused.value = false;
  213. }
  214. }, null), _createVNode("span", {
  215. "ref": measureRef,
  216. "class": "".concat(selectionPrefixCls.value, "-search-mirror"),
  217. "aria-hidden": true
  218. }, [inputValue.value, _createTextVNode("\xA0")])]);
  219. // >>> Selections
  220. var selectionNode = _createVNode(Overflow, {
  221. "prefixCls": "".concat(selectionPrefixCls.value, "-overflow"),
  222. "data": values,
  223. "renderItem": renderItem,
  224. "renderRest": renderRest,
  225. "suffix": inputNode,
  226. "itemKey": "key",
  227. "maxCount": props.maxTagCount,
  228. "key": "overflow"
  229. }, null);
  230. return _createVNode(_Fragment, null, [selectionNode, !values.length && !inputValue.value && _createVNode("span", {
  231. "class": "".concat(selectionPrefixCls.value, "-placeholder")
  232. }, [placeholder])]);
  233. };
  234. }
  235. });
  236. export default SelectSelector;