BaseSelect.js 27 KB

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