BaseSelect.js 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724
  1. import _typeof from "@babel/runtime/helpers/esm/typeof";
  2. import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
  3. import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
  4. import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
  5. import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
  6. import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
  7. var _excluded = ["prefixCls", "id", "open", "defaultOpen", "mode", "showSearch", "searchValue", "onSearch", "allowClear", "clearIcon", "showArrow", "inputIcon", "disabled", "loading", "getInputElement", "getPopupContainer", "placement", "animation", "transitionName", "dropdownStyle", "dropdownClassName", "dropdownMatchSelectWidth", "dropdownRender", "dropdownAlign", "showAction", "direction", "tokenSeparators", "tagRender", "optionLabelRender", "onPopupScroll", "onDropdownVisibleChange", "onFocus", "onBlur", "onKeyup", "onKeydown", "onMousedown", "onClear", "omitDomProps", "getRawInputElement", "displayValues", "onDisplayValuesChange", "emptyOptions", "activeDescendantId", "activeValue", "OptionList"];
  8. import { resolveDirective as _resolveDirective, createTextVNode as _createTextVNode, createVNode as _createVNode } from "vue";
  9. import { getSeparatedContent } from './utils/valueUtil';
  10. import SelectTrigger from './SelectTrigger';
  11. import Selector from './Selector';
  12. import useSelectTriggerControl from './hooks/useSelectTriggerControl';
  13. import useDelayReset from './hooks/useDelayReset';
  14. import TransBtn from './TransBtn';
  15. import useLock from './hooks/useLock';
  16. import { useProvideBaseSelectProps } from './hooks/useBaseProps';
  17. import { computed, defineComponent, getCurrentInstance, onBeforeUnmount, onMounted, provide, ref, toRefs, watch, watchEffect } from 'vue';
  18. import PropTypes from '../_util/vue-types';
  19. import { initDefaultProps, isValidElement } from '../_util/props-util';
  20. import isMobile from '../vc-util/isMobile';
  21. import KeyCode from '../_util/KeyCode';
  22. import { toReactive } from '../_util/toReactive';
  23. import classNames from '../_util/classNames';
  24. import createRef from '../_util/createRef';
  25. import useInjectLegacySelectContext from '../vc-tree-select/LegacyContext';
  26. import { cloneElement } from '../_util/vnode';
  27. var DEFAULT_OMIT_PROPS = ['value', 'onChange', 'removeIcon', 'placeholder', 'autofocus', 'maxTagCount', 'maxTagTextLength', 'maxTagPlaceholder', 'choiceTransitionName', 'onInputKeyDown', 'onPopupScroll', 'tabindex', 'OptionList', 'notFoundContent'];
  28. var baseSelectPrivateProps = function baseSelectPrivateProps() {
  29. return {
  30. prefixCls: String,
  31. id: String,
  32. omitDomProps: Array,
  33. // >>> Value
  34. displayValues: Array,
  35. onDisplayValuesChange: Function,
  36. // >>> Active
  37. /** Current dropdown list active item string value */
  38. activeValue: String,
  39. /** Link search input with target element */
  40. activeDescendantId: String,
  41. onActiveValueChange: Function,
  42. // >>> Search
  43. searchValue: String,
  44. /** Trigger onSearch, return false to prevent trigger open event */
  45. onSearch: Function,
  46. /** Trigger when search text match the `tokenSeparators`. Will provide split content */
  47. onSearchSplit: Function,
  48. maxLength: Number,
  49. OptionList: PropTypes.any,
  50. /** Tell if provided `options` is empty */
  51. emptyOptions: Boolean
  52. };
  53. };
  54. export var baseSelectPropsWithoutPrivate = function baseSelectPropsWithoutPrivate() {
  55. return {
  56. showSearch: {
  57. type: Boolean,
  58. default: undefined
  59. },
  60. tagRender: {
  61. type: Function
  62. },
  63. optionLabelRender: {
  64. type: Function
  65. },
  66. direction: {
  67. type: String
  68. },
  69. // MISC
  70. tabindex: Number,
  71. autofocus: Boolean,
  72. notFoundContent: PropTypes.any,
  73. placeholder: PropTypes.any,
  74. onClear: Function,
  75. choiceTransitionName: String,
  76. // >>> Mode
  77. mode: String,
  78. // >>> Status
  79. disabled: {
  80. type: Boolean,
  81. default: undefined
  82. },
  83. loading: {
  84. type: Boolean,
  85. default: undefined
  86. },
  87. // >>> Open
  88. open: {
  89. type: Boolean,
  90. default: undefined
  91. },
  92. defaultOpen: {
  93. type: Boolean,
  94. default: undefined
  95. },
  96. onDropdownVisibleChange: {
  97. type: Function
  98. },
  99. // >>> Customize Input
  100. /** @private Internal usage. Do not use in your production. */
  101. getInputElement: {
  102. type: Function
  103. },
  104. /** @private Internal usage. Do not use in your production. */
  105. getRawInputElement: {
  106. type: Function
  107. },
  108. // >>> Selector
  109. maxTagTextLength: Number,
  110. maxTagCount: {
  111. type: [String, Number]
  112. },
  113. maxTagPlaceholder: PropTypes.any,
  114. // >>> Search
  115. tokenSeparators: {
  116. type: Array
  117. },
  118. // >>> Icons
  119. allowClear: {
  120. type: Boolean,
  121. default: undefined
  122. },
  123. showArrow: {
  124. type: Boolean,
  125. default: undefined
  126. },
  127. inputIcon: PropTypes.any,
  128. /** Clear all icon */
  129. clearIcon: PropTypes.any,
  130. /** Selector remove icon */
  131. removeIcon: PropTypes.any,
  132. // >>> Dropdown
  133. animation: String,
  134. transitionName: String,
  135. dropdownStyle: {
  136. type: Object
  137. },
  138. dropdownClassName: String,
  139. dropdownMatchSelectWidth: {
  140. type: [Boolean, Number],
  141. default: undefined
  142. },
  143. dropdownRender: {
  144. type: Function
  145. },
  146. dropdownAlign: Object,
  147. placement: {
  148. type: String
  149. },
  150. getPopupContainer: {
  151. type: Function
  152. },
  153. // >>> Focus
  154. showAction: {
  155. type: Array
  156. },
  157. onBlur: {
  158. type: Function
  159. },
  160. onFocus: {
  161. type: Function
  162. },
  163. // >>> Rest Events
  164. onKeyup: Function,
  165. onKeydown: Function,
  166. onMousedown: Function,
  167. onPopupScroll: Function,
  168. onInputKeyDown: Function,
  169. onMouseenter: Function,
  170. onMouseleave: Function,
  171. onClick: Function
  172. };
  173. };
  174. var baseSelectProps = function baseSelectProps() {
  175. return _objectSpread(_objectSpread({}, baseSelectPrivateProps()), baseSelectPropsWithoutPrivate());
  176. };
  177. export function isMultiple(mode) {
  178. return mode === 'tags' || mode === 'multiple';
  179. }
  180. export default defineComponent({
  181. compatConfig: {
  182. MODE: 3
  183. },
  184. name: 'BaseSelect',
  185. inheritAttrs: false,
  186. props: initDefaultProps(baseSelectProps(), {
  187. showAction: [],
  188. notFoundContent: 'Not Found'
  189. }),
  190. setup: function setup(props, _ref) {
  191. var attrs = _ref.attrs,
  192. expose = _ref.expose,
  193. slots = _ref.slots;
  194. var multiple = computed(function () {
  195. return isMultiple(props.mode);
  196. });
  197. var mergedShowSearch = computed(function () {
  198. return props.showSearch !== undefined ? props.showSearch : multiple.value || props.mode === 'combobox';
  199. });
  200. var mobile = ref(false);
  201. onMounted(function () {
  202. mobile.value = isMobile();
  203. });
  204. var legacyTreeSelectContext = useInjectLegacySelectContext();
  205. // ============================== Refs ==============================
  206. var containerRef = ref(null);
  207. var selectorDomRef = createRef();
  208. var triggerRef = ref(null);
  209. var selectorRef = ref(null);
  210. var listRef = ref(null);
  211. /** Used for component focused management */
  212. var _useDelayReset = useDelayReset(),
  213. _useDelayReset2 = _slicedToArray(_useDelayReset, 3),
  214. mockFocused = _useDelayReset2[0],
  215. setMockFocused = _useDelayReset2[1],
  216. cancelSetMockFocused = _useDelayReset2[2];
  217. var focus = function focus() {
  218. var _selectorRef$value;
  219. (_selectorRef$value = selectorRef.value) === null || _selectorRef$value === void 0 ? void 0 : _selectorRef$value.focus();
  220. };
  221. var blur = function blur() {
  222. var _selectorRef$value2;
  223. (_selectorRef$value2 = selectorRef.value) === null || _selectorRef$value2 === void 0 ? void 0 : _selectorRef$value2.blur();
  224. };
  225. expose({
  226. focus: focus,
  227. blur: blur,
  228. scrollTo: function scrollTo(arg) {
  229. var _listRef$value;
  230. return (_listRef$value = listRef.value) === null || _listRef$value === void 0 ? void 0 : _listRef$value.scrollTo(arg);
  231. }
  232. });
  233. var mergedSearchValue = computed(function () {
  234. var _props$displayValues$;
  235. if (props.mode !== 'combobox') {
  236. return props.searchValue;
  237. }
  238. var val = (_props$displayValues$ = props.displayValues[0]) === null || _props$displayValues$ === void 0 ? void 0 : _props$displayValues$.value;
  239. return typeof val === 'string' || typeof val === 'number' ? String(val) : '';
  240. });
  241. // ============================== Open ==============================
  242. var initOpen = props.open !== undefined ? props.open : props.defaultOpen;
  243. var innerOpen = ref(initOpen);
  244. var mergedOpen = ref(initOpen);
  245. var setInnerOpen = function setInnerOpen(val) {
  246. innerOpen.value = props.open !== undefined ? props.open : val;
  247. mergedOpen.value = innerOpen.value;
  248. };
  249. watch(function () {
  250. return props.open;
  251. }, function () {
  252. setInnerOpen(props.open);
  253. });
  254. // Not trigger `open` in `combobox` when `notFoundContent` is empty
  255. var emptyListContent = computed(function () {
  256. return !props.notFoundContent && props.emptyOptions;
  257. });
  258. watchEffect(function () {
  259. mergedOpen.value = innerOpen.value;
  260. if (props.disabled || emptyListContent.value && mergedOpen.value && props.mode === 'combobox') {
  261. mergedOpen.value = false;
  262. }
  263. });
  264. var triggerOpen = computed(function () {
  265. return emptyListContent.value ? false : mergedOpen.value;
  266. });
  267. var onToggleOpen = function onToggleOpen(newOpen) {
  268. var nextOpen = newOpen !== undefined ? newOpen : !mergedOpen.value;
  269. if (innerOpen.value !== nextOpen && !props.disabled) {
  270. setInnerOpen(nextOpen);
  271. if (props.onDropdownVisibleChange) {
  272. props.onDropdownVisibleChange(nextOpen);
  273. }
  274. }
  275. };
  276. var tokenWithEnter = computed(function () {
  277. return (props.tokenSeparators || []).some(function (tokenSeparator) {
  278. return ['\n', '\r\n'].includes(tokenSeparator);
  279. });
  280. });
  281. var onInternalSearch = function onInternalSearch(searchText, fromTyping, isCompositing) {
  282. var _props$onActiveValueC;
  283. var ret = true;
  284. var newSearchText = searchText;
  285. (_props$onActiveValueC = props.onActiveValueChange) === null || _props$onActiveValueC === void 0 ? void 0 : _props$onActiveValueC.call(props, null);
  286. // Check if match the `tokenSeparators`
  287. var patchLabels = isCompositing ? null : getSeparatedContent(searchText, props.tokenSeparators);
  288. // Ignore combobox since it's not split-able
  289. if (props.mode !== 'combobox' && patchLabels) {
  290. var _props$onSearchSplit;
  291. newSearchText = '';
  292. (_props$onSearchSplit = props.onSearchSplit) === null || _props$onSearchSplit === void 0 ? void 0 : _props$onSearchSplit.call(props, patchLabels);
  293. // Should close when paste finish
  294. onToggleOpen(false);
  295. // Tell Selector that break next actions
  296. ret = false;
  297. }
  298. if (props.onSearch && mergedSearchValue.value !== newSearchText) {
  299. props.onSearch(newSearchText, {
  300. source: fromTyping ? 'typing' : 'effect'
  301. });
  302. }
  303. return ret;
  304. };
  305. // Only triggered when menu is closed & mode is tags
  306. // If menu is open, OptionList will take charge
  307. // If mode isn't tags, press enter is not meaningful when you can't see any option
  308. var onInternalSearchSubmit = function onInternalSearchSubmit(searchText) {
  309. var _props$onSearch;
  310. // prevent empty tags from appearing when you click the Enter button
  311. if (!searchText || !searchText.trim()) {
  312. return;
  313. }
  314. (_props$onSearch = props.onSearch) === null || _props$onSearch === void 0 ? void 0 : _props$onSearch.call(props, searchText, {
  315. source: 'submit'
  316. });
  317. };
  318. // Close will clean up single mode search text
  319. watch(mergedOpen, function () {
  320. if (!mergedOpen.value && !multiple.value && props.mode !== 'combobox') {
  321. onInternalSearch('', false, false);
  322. }
  323. }, {
  324. immediate: true,
  325. flush: 'post'
  326. });
  327. // ============================ Disabled ============================
  328. // Close dropdown & remove focus state when disabled change
  329. watch(function () {
  330. return props.disabled;
  331. }, function () {
  332. if (innerOpen.value && !!props.disabled) {
  333. setInnerOpen(false);
  334. }
  335. }, {
  336. immediate: true
  337. });
  338. // ============================ Keyboard ============================
  339. /**
  340. * We record input value here to check if can press to clean up by backspace
  341. * - null: Key is not down, this is reset by key up
  342. * - true: Search text is empty when first time backspace down
  343. * - false: Search text is not empty when first time backspace down
  344. */
  345. var _useLock = useLock(),
  346. _useLock2 = _slicedToArray(_useLock, 2),
  347. getClearLock = _useLock2[0],
  348. setClearLock = _useLock2[1];
  349. // KeyDown
  350. var onInternalKeyDown = function onInternalKeyDown(event) {
  351. var _props$onKeydown;
  352. var clearLock = getClearLock();
  353. var which = event.which;
  354. if (which === KeyCode.ENTER) {
  355. // Do not submit form when type in the input
  356. if (props.mode !== 'combobox') {
  357. event.preventDefault();
  358. }
  359. // We only manage open state here, close logic should handle by list component
  360. if (!mergedOpen.value) {
  361. onToggleOpen(true);
  362. }
  363. }
  364. setClearLock(!!mergedSearchValue.value);
  365. // Remove value by `backspace`
  366. if (which === KeyCode.BACKSPACE && !clearLock && multiple.value && !mergedSearchValue.value && props.displayValues.length) {
  367. var cloneDisplayValues = _toConsumableArray(props.displayValues);
  368. var removedDisplayValue = null;
  369. for (var i = cloneDisplayValues.length - 1; i >= 0; i -= 1) {
  370. var current = cloneDisplayValues[i];
  371. if (!current.disabled) {
  372. cloneDisplayValues.splice(i, 1);
  373. removedDisplayValue = current;
  374. break;
  375. }
  376. }
  377. if (removedDisplayValue) {
  378. props.onDisplayValuesChange(cloneDisplayValues, {
  379. type: 'remove',
  380. values: [removedDisplayValue]
  381. });
  382. }
  383. }
  384. for (var _len = arguments.length, rest = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
  385. rest[_key - 1] = arguments[_key];
  386. }
  387. if (mergedOpen.value && listRef.value) {
  388. var _listRef$value2;
  389. (_listRef$value2 = listRef.value).onKeydown.apply(_listRef$value2, [event].concat(rest));
  390. }
  391. (_props$onKeydown = props.onKeydown) === null || _props$onKeydown === void 0 ? void 0 : _props$onKeydown.call.apply(_props$onKeydown, [props, event].concat(rest));
  392. };
  393. // KeyUp
  394. var onInternalKeyUp = function onInternalKeyUp(event) {
  395. for (var _len2 = arguments.length, rest = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
  396. rest[_key2 - 1] = arguments[_key2];
  397. }
  398. if (mergedOpen.value && listRef.value) {
  399. var _listRef$value3;
  400. (_listRef$value3 = listRef.value).onKeyup.apply(_listRef$value3, [event].concat(rest));
  401. }
  402. if (props.onKeyup) {
  403. props.onKeyup.apply(props, [event].concat(rest));
  404. }
  405. };
  406. // ============================ Selector ============================
  407. var onSelectorRemove = function onSelectorRemove(val) {
  408. var newValues = props.displayValues.filter(function (i) {
  409. return i !== val;
  410. });
  411. props.onDisplayValuesChange(newValues, {
  412. type: 'remove',
  413. values: [val]
  414. });
  415. };
  416. // ========================== Focus / Blur ==========================
  417. /** Record real focus status */
  418. var focusRef = ref(false);
  419. var onContainerFocus = function onContainerFocus() {
  420. setMockFocused(true);
  421. if (!props.disabled) {
  422. if (props.onFocus && !focusRef.value) {
  423. props.onFocus.apply(props, arguments);
  424. }
  425. // `showAction` should handle `focus` if set
  426. if (props.showAction && props.showAction.includes('focus')) {
  427. onToggleOpen(true);
  428. }
  429. }
  430. focusRef.value = true;
  431. };
  432. var onContainerBlur = function onContainerBlur() {
  433. setMockFocused(false, function () {
  434. focusRef.value = false;
  435. onToggleOpen(false);
  436. });
  437. if (props.disabled) {
  438. return;
  439. }
  440. var searchVal = mergedSearchValue.value;
  441. if (searchVal) {
  442. // `tags` mode should move `searchValue` into values
  443. if (props.mode === 'tags') {
  444. props.onSearch(searchVal, {
  445. source: 'submit'
  446. });
  447. } else if (props.mode === 'multiple') {
  448. // `multiple` mode only clean the search value but not trigger event
  449. props.onSearch('', {
  450. source: 'blur'
  451. });
  452. }
  453. }
  454. if (props.onBlur) {
  455. props.onBlur.apply(props, arguments);
  456. }
  457. };
  458. provide('VCSelectContainerEvent', {
  459. focus: onContainerFocus,
  460. blur: onContainerBlur
  461. });
  462. // Give focus back of Select
  463. var activeTimeoutIds = [];
  464. onMounted(function () {
  465. activeTimeoutIds.forEach(function (timeoutId) {
  466. return clearTimeout(timeoutId);
  467. });
  468. activeTimeoutIds.splice(0, activeTimeoutIds.length);
  469. });
  470. onBeforeUnmount(function () {
  471. activeTimeoutIds.forEach(function (timeoutId) {
  472. return clearTimeout(timeoutId);
  473. });
  474. activeTimeoutIds.splice(0, activeTimeoutIds.length);
  475. });
  476. var onInternalMouseDown = function onInternalMouseDown(event) {
  477. var _triggerRef$value, _props$onMousedown;
  478. var target = event.target;
  479. var popupElement = (_triggerRef$value = triggerRef.value) === null || _triggerRef$value === void 0 ? void 0 : _triggerRef$value.getPopupElement();
  480. // We should give focus back to selector if clicked item is not focusable
  481. if (popupElement && popupElement.contains(target)) {
  482. var timeoutId = setTimeout(function () {
  483. var index = activeTimeoutIds.indexOf(timeoutId);
  484. if (index !== -1) {
  485. activeTimeoutIds.splice(index, 1);
  486. }
  487. cancelSetMockFocused();
  488. if (!mobile.value && !popupElement.contains(document.activeElement)) {
  489. var _selectorRef$value3;
  490. (_selectorRef$value3 = selectorRef.value) === null || _selectorRef$value3 === void 0 ? void 0 : _selectorRef$value3.focus();
  491. }
  492. });
  493. activeTimeoutIds.push(timeoutId);
  494. }
  495. for (var _len3 = arguments.length, restArgs = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
  496. restArgs[_key3 - 1] = arguments[_key3];
  497. }
  498. (_props$onMousedown = props.onMousedown) === null || _props$onMousedown === void 0 ? void 0 : _props$onMousedown.call.apply(_props$onMousedown, [props, event].concat(restArgs));
  499. };
  500. // ============================= Dropdown ==============================
  501. var containerWidth = ref(null);
  502. var instance = getCurrentInstance();
  503. var onPopupMouseEnter = function onPopupMouseEnter() {
  504. // We need force update here since popup dom is render async
  505. instance.update();
  506. };
  507. onMounted(function () {
  508. watch(triggerOpen, function () {
  509. if (triggerOpen.value) {
  510. var _containerRef$value;
  511. var newWidth = Math.ceil((_containerRef$value = containerRef.value) === null || _containerRef$value === void 0 ? void 0 : _containerRef$value.offsetWidth);
  512. if (containerWidth.value !== newWidth && !Number.isNaN(newWidth)) {
  513. containerWidth.value = newWidth;
  514. }
  515. }
  516. }, {
  517. immediate: true,
  518. flush: 'post'
  519. });
  520. });
  521. // Close when click on non-select element
  522. useSelectTriggerControl([containerRef, triggerRef], triggerOpen, onToggleOpen);
  523. useProvideBaseSelectProps(toReactive(_objectSpread(_objectSpread({}, toRefs(props)), {}, {
  524. open: mergedOpen,
  525. triggerOpen: triggerOpen,
  526. showSearch: mergedShowSearch,
  527. multiple: multiple,
  528. toggleOpen: onToggleOpen
  529. })));
  530. return function () {
  531. var _classNames2;
  532. var _props$attrs = _objectSpread(_objectSpread({}, props), attrs),
  533. prefixCls = _props$attrs.prefixCls,
  534. id = _props$attrs.id,
  535. open = _props$attrs.open,
  536. defaultOpen = _props$attrs.defaultOpen,
  537. mode = _props$attrs.mode,
  538. showSearch = _props$attrs.showSearch,
  539. searchValue = _props$attrs.searchValue,
  540. onSearch = _props$attrs.onSearch,
  541. allowClear = _props$attrs.allowClear,
  542. clearIcon = _props$attrs.clearIcon,
  543. showArrow = _props$attrs.showArrow,
  544. inputIcon = _props$attrs.inputIcon,
  545. disabled = _props$attrs.disabled,
  546. loading = _props$attrs.loading,
  547. getInputElement = _props$attrs.getInputElement,
  548. getPopupContainer = _props$attrs.getPopupContainer,
  549. placement = _props$attrs.placement,
  550. animation = _props$attrs.animation,
  551. transitionName = _props$attrs.transitionName,
  552. dropdownStyle = _props$attrs.dropdownStyle,
  553. dropdownClassName = _props$attrs.dropdownClassName,
  554. dropdownMatchSelectWidth = _props$attrs.dropdownMatchSelectWidth,
  555. dropdownRender = _props$attrs.dropdownRender,
  556. dropdownAlign = _props$attrs.dropdownAlign,
  557. showAction = _props$attrs.showAction,
  558. direction = _props$attrs.direction,
  559. tokenSeparators = _props$attrs.tokenSeparators,
  560. tagRender = _props$attrs.tagRender,
  561. optionLabelRender = _props$attrs.optionLabelRender,
  562. onPopupScroll = _props$attrs.onPopupScroll,
  563. onDropdownVisibleChange = _props$attrs.onDropdownVisibleChange,
  564. onFocus = _props$attrs.onFocus,
  565. onBlur = _props$attrs.onBlur,
  566. onKeyup = _props$attrs.onKeyup,
  567. onKeydown = _props$attrs.onKeydown,
  568. onMousedown = _props$attrs.onMousedown,
  569. onClear = _props$attrs.onClear,
  570. omitDomProps = _props$attrs.omitDomProps,
  571. getRawInputElement = _props$attrs.getRawInputElement,
  572. displayValues = _props$attrs.displayValues,
  573. onDisplayValuesChange = _props$attrs.onDisplayValuesChange,
  574. emptyOptions = _props$attrs.emptyOptions,
  575. activeDescendantId = _props$attrs.activeDescendantId,
  576. activeValue = _props$attrs.activeValue,
  577. OptionList = _props$attrs.OptionList,
  578. restProps = _objectWithoutProperties(_props$attrs, _excluded);
  579. // ============================= Input ==============================
  580. // Only works in `combobox`
  581. var customizeInputElement = mode === 'combobox' && getInputElement && getInputElement() || null;
  582. // Used for customize replacement for `vc-cascader`
  583. var customizeRawInputElement = typeof getRawInputElement === 'function' && getRawInputElement();
  584. var domProps = _objectSpread({}, restProps);
  585. // Used for raw custom input trigger
  586. var onTriggerVisibleChange;
  587. if (customizeRawInputElement) {
  588. onTriggerVisibleChange = function onTriggerVisibleChange(newOpen) {
  589. onToggleOpen(newOpen);
  590. };
  591. }
  592. DEFAULT_OMIT_PROPS.forEach(function (propName) {
  593. delete domProps[propName];
  594. });
  595. omitDomProps === null || omitDomProps === void 0 ? void 0 : omitDomProps.forEach(function (propName) {
  596. delete domProps[propName];
  597. });
  598. // ============================= Arrow ==============================
  599. var mergedShowArrow = showArrow !== undefined ? showArrow : loading || !multiple.value && mode !== 'combobox';
  600. var arrowNode;
  601. if (mergedShowArrow) {
  602. arrowNode = _createVNode(TransBtn, {
  603. "class": classNames("".concat(prefixCls, "-arrow"), _defineProperty({}, "".concat(prefixCls, "-arrow-loading"), loading)),
  604. "customizeIcon": inputIcon,
  605. "customizeIconProps": {
  606. loading: loading,
  607. searchValue: mergedSearchValue.value,
  608. open: mergedOpen.value,
  609. focused: mockFocused.value,
  610. showSearch: mergedShowSearch.value
  611. }
  612. }, null);
  613. }
  614. // ============================= Clear ==============================
  615. var clearNode;
  616. var onClearMouseDown = function onClearMouseDown() {
  617. onClear === null || onClear === void 0 ? void 0 : onClear();
  618. onDisplayValuesChange([], {
  619. type: 'clear',
  620. values: displayValues
  621. });
  622. onInternalSearch('', false, false);
  623. };
  624. if (!disabled && allowClear && (displayValues.length || mergedSearchValue.value)) {
  625. clearNode = _createVNode(TransBtn, {
  626. "class": "".concat(prefixCls, "-clear"),
  627. "onMousedown": onClearMouseDown,
  628. "customizeIcon": clearIcon
  629. }, {
  630. default: function _default() {
  631. return [_createTextVNode("\xD7")];
  632. }
  633. });
  634. }
  635. // =========================== OptionList ===========================
  636. var optionList = _createVNode(OptionList, {
  637. "ref": listRef
  638. }, _objectSpread(_objectSpread({}, legacyTreeSelectContext.customSlots), {}, {
  639. option: slots.option
  640. }));
  641. // ============================= Select =============================
  642. var mergedClassName = classNames(prefixCls, attrs.class, (_classNames2 = {}, _defineProperty(_classNames2, "".concat(prefixCls, "-focused"), mockFocused.value), _defineProperty(_classNames2, "".concat(prefixCls, "-multiple"), multiple.value), _defineProperty(_classNames2, "".concat(prefixCls, "-single"), !multiple.value), _defineProperty(_classNames2, "".concat(prefixCls, "-allow-clear"), allowClear), _defineProperty(_classNames2, "".concat(prefixCls, "-show-arrow"), mergedShowArrow), _defineProperty(_classNames2, "".concat(prefixCls, "-disabled"), disabled), _defineProperty(_classNames2, "".concat(prefixCls, "-loading"), loading), _defineProperty(_classNames2, "".concat(prefixCls, "-open"), mergedOpen.value), _defineProperty(_classNames2, "".concat(prefixCls, "-customize-input"), customizeInputElement), _defineProperty(_classNames2, "".concat(prefixCls, "-show-search"), mergedShowSearch.value), _classNames2));
  643. // >>> Selector
  644. var selectorNode = _createVNode(SelectTrigger, {
  645. "ref": triggerRef,
  646. "disabled": disabled,
  647. "prefixCls": prefixCls,
  648. "visible": triggerOpen.value,
  649. "popupElement": optionList,
  650. "containerWidth": containerWidth.value,
  651. "animation": animation,
  652. "transitionName": transitionName,
  653. "dropdownStyle": dropdownStyle,
  654. "dropdownClassName": dropdownClassName,
  655. "direction": direction,
  656. "dropdownMatchSelectWidth": dropdownMatchSelectWidth,
  657. "dropdownRender": dropdownRender,
  658. "dropdownAlign": dropdownAlign,
  659. "placement": placement,
  660. "getPopupContainer": getPopupContainer,
  661. "empty": emptyOptions,
  662. "getTriggerDOMNode": function getTriggerDOMNode() {
  663. return selectorDomRef.current;
  664. },
  665. "onPopupVisibleChange": onTriggerVisibleChange,
  666. "onPopupMouseEnter": onPopupMouseEnter
  667. }, {
  668. default: function _default() {
  669. return customizeRawInputElement ? isValidElement(customizeRawInputElement) && cloneElement(customizeRawInputElement, {
  670. ref: selectorDomRef
  671. }, false, true) : _createVNode(Selector, _objectSpread(_objectSpread({}, props), {}, {
  672. "domRef": selectorDomRef,
  673. "prefixCls": prefixCls,
  674. "inputElement": customizeInputElement,
  675. "ref": selectorRef,
  676. "id": id,
  677. "showSearch": mergedShowSearch.value,
  678. "mode": mode,
  679. "activeDescendantId": activeDescendantId,
  680. "tagRender": tagRender,
  681. "optionLabelRender": optionLabelRender,
  682. "values": displayValues,
  683. "open": mergedOpen.value,
  684. "onToggleOpen": onToggleOpen,
  685. "activeValue": activeValue,
  686. "searchValue": mergedSearchValue.value,
  687. "onSearch": onInternalSearch,
  688. "onSearchSubmit": onInternalSearchSubmit,
  689. "onRemove": onSelectorRemove,
  690. "tokenWithEnter": tokenWithEnter.value
  691. }), null);
  692. }
  693. });
  694. // >>> Render
  695. var renderNode;
  696. // Render raw
  697. if (customizeRawInputElement) {
  698. renderNode = selectorNode;
  699. } else {
  700. renderNode = _createVNode("div", _objectSpread(_objectSpread({}, domProps), {}, {
  701. "class": mergedClassName,
  702. "ref": containerRef,
  703. "onMousedown": onInternalMouseDown,
  704. "onKeydown": onInternalKeyDown,
  705. "onKeyup": onInternalKeyUp
  706. }), [mockFocused.value && !mergedOpen.value && _createVNode("span", {
  707. "style": {
  708. width: 0,
  709. height: 0,
  710. position: 'absolute',
  711. overflow: 'hidden',
  712. opacity: 0
  713. },
  714. "aria-live": "polite"
  715. }, ["".concat(displayValues.map(function (_ref2) {
  716. var label = _ref2.label,
  717. value = _ref2.value;
  718. return ['number', 'string'].includes(_typeof(label)) ? label : value;
  719. }).join(', '))]), selectorNode, arrowNode, clearNode]);
  720. }
  721. return renderNode;
  722. };
  723. }
  724. });