BaseSelect.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743
  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. }
  272. };
  273. const tokenWithEnter = (0, _vue.computed)(() => (props.tokenSeparators || []).some(tokenSeparator => ['\n', '\r\n'].includes(tokenSeparator)));
  274. const onInternalSearch = (searchText, fromTyping, isCompositing) => {
  275. var _a, _b;
  276. let ret = true;
  277. let newSearchText = searchText;
  278. (_a = props.onActiveValueChange) === null || _a === void 0 ? void 0 : _a.call(props, null);
  279. // Check if match the `tokenSeparators`
  280. const patchLabels = isCompositing ? null : (0, _valueUtil.getSeparatedContent)(searchText, props.tokenSeparators);
  281. // Ignore combobox since it's not split-able
  282. if (props.mode !== 'combobox' && patchLabels) {
  283. newSearchText = '';
  284. (_b = props.onSearchSplit) === null || _b === void 0 ? void 0 : _b.call(props, patchLabels);
  285. // Should close when paste finish
  286. onToggleOpen(false);
  287. // Tell Selector that break next actions
  288. ret = false;
  289. }
  290. if (props.onSearch && mergedSearchValue.value !== newSearchText) {
  291. props.onSearch(newSearchText, {
  292. source: fromTyping ? 'typing' : 'effect'
  293. });
  294. }
  295. return ret;
  296. };
  297. // Only triggered when menu is closed & mode is tags
  298. // If menu is open, OptionList will take charge
  299. // If mode isn't tags, press enter is not meaningful when you can't see any option
  300. const onInternalSearchSubmit = searchText => {
  301. var _a;
  302. // prevent empty tags from appearing when you click the Enter button
  303. if (!searchText || !searchText.trim()) {
  304. return;
  305. }
  306. (_a = props.onSearch) === null || _a === void 0 ? void 0 : _a.call(props, searchText, {
  307. source: 'submit'
  308. });
  309. };
  310. // Close will clean up single mode search text
  311. (0, _vue.watch)(mergedOpen, () => {
  312. if (!mergedOpen.value && !multiple.value && props.mode !== 'combobox') {
  313. onInternalSearch('', false, false);
  314. }
  315. }, {
  316. immediate: true,
  317. flush: 'post'
  318. });
  319. // ============================ Disabled ============================
  320. // Close dropdown & remove focus state when disabled change
  321. (0, _vue.watch)(() => props.disabled, () => {
  322. if (innerOpen.value && !!props.disabled) {
  323. setInnerOpen(false);
  324. }
  325. if (props.disabled && !blurRef.value) {
  326. setMockFocused(false);
  327. }
  328. }, {
  329. immediate: true
  330. });
  331. // ============================ Keyboard ============================
  332. /**
  333. * We record input value here to check if can press to clean up by backspace
  334. * - null: Key is not down, this is reset by key up
  335. * - true: Search text is empty when first time backspace down
  336. * - false: Search text is not empty when first time backspace down
  337. */
  338. const [getClearLock, setClearLock] = (0, _useLock.default)();
  339. // KeyDown
  340. const onInternalKeyDown = function (event) {
  341. var _a;
  342. const clearLock = getClearLock();
  343. const {
  344. which
  345. } = event;
  346. if (which === _KeyCode.default.ENTER) {
  347. // Do not submit form when type in the input
  348. if (props.mode !== 'combobox') {
  349. event.preventDefault();
  350. }
  351. // We only manage open state here, close logic should handle by list component
  352. if (!mergedOpen.value) {
  353. onToggleOpen(true);
  354. }
  355. }
  356. setClearLock(!!mergedSearchValue.value);
  357. // Remove value by `backspace`
  358. if (which === _KeyCode.default.BACKSPACE && !clearLock && multiple.value && !mergedSearchValue.value && props.displayValues.length) {
  359. const cloneDisplayValues = [...props.displayValues];
  360. let removedDisplayValue = null;
  361. for (let i = cloneDisplayValues.length - 1; i >= 0; i -= 1) {
  362. const current = cloneDisplayValues[i];
  363. if (!current.disabled) {
  364. cloneDisplayValues.splice(i, 1);
  365. removedDisplayValue = current;
  366. break;
  367. }
  368. }
  369. if (removedDisplayValue) {
  370. props.onDisplayValuesChange(cloneDisplayValues, {
  371. type: 'remove',
  372. values: [removedDisplayValue]
  373. });
  374. }
  375. }
  376. for (var _len = arguments.length, rest = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
  377. rest[_key - 1] = arguments[_key];
  378. }
  379. if (mergedOpen.value && listRef.value) {
  380. listRef.value.onKeydown(event, ...rest);
  381. }
  382. (_a = props.onKeydown) === null || _a === void 0 ? void 0 : _a.call(props, event, ...rest);
  383. };
  384. // KeyUp
  385. const onInternalKeyUp = function (event) {
  386. for (var _len2 = arguments.length, rest = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
  387. rest[_key2 - 1] = arguments[_key2];
  388. }
  389. if (mergedOpen.value && listRef.value) {
  390. listRef.value.onKeyup(event, ...rest);
  391. }
  392. if (props.onKeyup) {
  393. props.onKeyup(event, ...rest);
  394. }
  395. };
  396. // ============================ Selector ============================
  397. const onSelectorRemove = val => {
  398. const newValues = props.displayValues.filter(i => i !== val);
  399. props.onDisplayValuesChange(newValues, {
  400. type: 'remove',
  401. values: [val]
  402. });
  403. };
  404. // ========================== Focus / Blur ==========================
  405. /** Record real focus status */
  406. const focusRef = (0, _vue.shallowRef)(false);
  407. const onContainerFocus = function () {
  408. setMockFocused(true);
  409. if (!props.disabled) {
  410. if (props.onFocus && !focusRef.value) {
  411. props.onFocus(...arguments);
  412. }
  413. // `showAction` should handle `focus` if set
  414. if (props.showAction && props.showAction.includes('focus')) {
  415. onToggleOpen(true);
  416. }
  417. }
  418. focusRef.value = true;
  419. };
  420. const popupFocused = (0, _vue.ref)(false);
  421. const onContainerBlur = function () {
  422. if (popupFocused.value) {
  423. return;
  424. }
  425. blurRef.value = true;
  426. setMockFocused(false, () => {
  427. focusRef.value = false;
  428. blurRef.value = false;
  429. onToggleOpen(false);
  430. });
  431. if (props.disabled) {
  432. return;
  433. }
  434. const searchVal = mergedSearchValue.value;
  435. if (searchVal) {
  436. // `tags` mode should move `searchValue` into values
  437. if (props.mode === 'tags') {
  438. props.onSearch(searchVal, {
  439. source: 'submit'
  440. });
  441. } else if (props.mode === 'multiple') {
  442. // `multiple` mode only clean the search value but not trigger event
  443. props.onSearch('', {
  444. source: 'blur'
  445. });
  446. }
  447. }
  448. if (props.onBlur) {
  449. props.onBlur(...arguments);
  450. }
  451. };
  452. const onPopupFocusin = () => {
  453. popupFocused.value = true;
  454. };
  455. const onPopupFocusout = () => {
  456. popupFocused.value = false;
  457. };
  458. (0, _vue.provide)('VCSelectContainerEvent', {
  459. focus: onContainerFocus,
  460. blur: onContainerBlur
  461. });
  462. // Give focus back of Select
  463. const activeTimeoutIds = [];
  464. (0, _vue.onMounted)(() => {
  465. activeTimeoutIds.forEach(timeoutId => clearTimeout(timeoutId));
  466. activeTimeoutIds.splice(0, activeTimeoutIds.length);
  467. });
  468. (0, _vue.onBeforeUnmount)(() => {
  469. activeTimeoutIds.forEach(timeoutId => clearTimeout(timeoutId));
  470. activeTimeoutIds.splice(0, activeTimeoutIds.length);
  471. });
  472. const onInternalMouseDown = function (event) {
  473. var _a, _b;
  474. const {
  475. target
  476. } = event;
  477. const popupElement = (_a = triggerRef.value) === null || _a === void 0 ? void 0 : _a.getPopupElement();
  478. // We should give focus back to selector if clicked item is not focusable
  479. if (popupElement && popupElement.contains(target)) {
  480. const timeoutId = setTimeout(() => {
  481. var _a;
  482. const index = activeTimeoutIds.indexOf(timeoutId);
  483. if (index !== -1) {
  484. activeTimeoutIds.splice(index, 1);
  485. }
  486. cancelSetMockFocused();
  487. if (!mobile.value && !popupElement.contains(document.activeElement)) {
  488. (_a = selectorRef.value) === null || _a === void 0 ? void 0 : _a.focus();
  489. }
  490. });
  491. activeTimeoutIds.push(timeoutId);
  492. }
  493. for (var _len3 = arguments.length, restArgs = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
  494. restArgs[_key3 - 1] = arguments[_key3];
  495. }
  496. (_b = props.onMousedown) === null || _b === void 0 ? void 0 : _b.call(props, event, ...restArgs);
  497. };
  498. // ============================= Dropdown ==============================
  499. const containerWidth = (0, _vue.shallowRef)(null);
  500. // const instance = getCurrentInstance();
  501. const onPopupMouseEnter = () => {
  502. // We need force update here since popup dom is render async
  503. // instance.update();
  504. };
  505. (0, _vue.onMounted)(() => {
  506. (0, _vue.watch)(triggerOpen, () => {
  507. var _a;
  508. if (triggerOpen.value) {
  509. const newWidth = Math.ceil((_a = containerRef.value) === null || _a === void 0 ? void 0 : _a.offsetWidth);
  510. if (containerWidth.value !== newWidth && !Number.isNaN(newWidth)) {
  511. containerWidth.value = newWidth;
  512. }
  513. }
  514. }, {
  515. immediate: true,
  516. flush: 'post'
  517. });
  518. });
  519. // Close when click on non-select element
  520. (0, _useSelectTriggerControl.default)([containerRef, triggerRef], triggerOpen, onToggleOpen);
  521. (0, _useBaseProps.useProvideBaseSelectProps)((0, _toReactive.toReactive)((0, _extends2.default)((0, _extends2.default)({}, (0, _vue.toRefs)(props)), {
  522. open: mergedOpen,
  523. triggerOpen,
  524. showSearch: mergedShowSearch,
  525. multiple,
  526. toggleOpen: onToggleOpen
  527. })));
  528. return () => {
  529. const _a = (0, _extends2.default)((0, _extends2.default)({}, props), attrs),
  530. {
  531. prefixCls,
  532. id,
  533. open,
  534. defaultOpen,
  535. mode,
  536. // Search related
  537. showSearch,
  538. searchValue,
  539. onSearch,
  540. // Icons
  541. allowClear,
  542. clearIcon,
  543. showArrow,
  544. inputIcon,
  545. // Others
  546. disabled,
  547. loading,
  548. getInputElement,
  549. getPopupContainer,
  550. placement,
  551. // Dropdown
  552. animation,
  553. transitionName,
  554. dropdownStyle,
  555. dropdownClassName,
  556. dropdownMatchSelectWidth,
  557. dropdownRender,
  558. dropdownAlign,
  559. showAction,
  560. direction,
  561. // Tags
  562. tokenSeparators,
  563. tagRender,
  564. optionLabelRender,
  565. // Events
  566. onPopupScroll,
  567. onDropdownVisibleChange,
  568. onFocus,
  569. onBlur,
  570. onKeyup,
  571. onKeydown,
  572. onMousedown,
  573. onClear,
  574. omitDomProps,
  575. getRawInputElement,
  576. displayValues,
  577. onDisplayValuesChange,
  578. emptyOptions,
  579. activeDescendantId,
  580. activeValue,
  581. OptionList
  582. } = _a,
  583. 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"]);
  584. // ============================= Input ==============================
  585. // Only works in `combobox`
  586. const customizeInputElement = mode === 'combobox' && getInputElement && getInputElement() || null;
  587. // Used for customize replacement for `vc-cascader`
  588. const customizeRawInputElement = typeof getRawInputElement === 'function' && getRawInputElement();
  589. const domProps = (0, _extends2.default)({}, restProps);
  590. // Used for raw custom input trigger
  591. let onTriggerVisibleChange;
  592. if (customizeRawInputElement) {
  593. onTriggerVisibleChange = newOpen => {
  594. onToggleOpen(newOpen);
  595. };
  596. }
  597. DEFAULT_OMIT_PROPS.forEach(propName => {
  598. delete domProps[propName];
  599. });
  600. omitDomProps === null || omitDomProps === void 0 ? void 0 : omitDomProps.forEach(propName => {
  601. delete domProps[propName];
  602. });
  603. // ============================= Arrow ==============================
  604. const mergedShowArrow = showArrow !== undefined ? showArrow : loading || !multiple.value && mode !== 'combobox';
  605. let arrowNode;
  606. if (mergedShowArrow) {
  607. arrowNode = (0, _vue.createVNode)(_TransBtn.default, {
  608. "class": (0, _classNames.default)(`${prefixCls}-arrow`, {
  609. [`${prefixCls}-arrow-loading`]: loading
  610. }),
  611. "customizeIcon": inputIcon,
  612. "customizeIconProps": {
  613. loading,
  614. searchValue: mergedSearchValue.value,
  615. open: mergedOpen.value,
  616. focused: mockFocused.value,
  617. showSearch: mergedShowSearch.value
  618. }
  619. }, null);
  620. }
  621. // ============================= Clear ==============================
  622. let clearNode;
  623. const onClearMouseDown = () => {
  624. onClear === null || onClear === void 0 ? void 0 : onClear();
  625. onDisplayValuesChange([], {
  626. type: 'clear',
  627. values: displayValues
  628. });
  629. onInternalSearch('', false, false);
  630. };
  631. if (!disabled && allowClear && (displayValues.length || mergedSearchValue.value)) {
  632. clearNode = (0, _vue.createVNode)(_TransBtn.default, {
  633. "class": `${prefixCls}-clear`,
  634. "onMousedown": onClearMouseDown,
  635. "customizeIcon": clearIcon
  636. }, {
  637. default: () => [(0, _vue.createTextVNode)("\xD7")]
  638. });
  639. }
  640. // =========================== OptionList ===========================
  641. const optionList = (0, _vue.createVNode)(OptionList, {
  642. "ref": listRef
  643. }, (0, _extends2.default)((0, _extends2.default)({}, legacyTreeSelectContext.customSlots), {
  644. option: slots.option
  645. }));
  646. // ============================= Select =============================
  647. const mergedClassName = (0, _classNames.default)(prefixCls, attrs.class, {
  648. [`${prefixCls}-focused`]: mockFocused.value,
  649. [`${prefixCls}-multiple`]: multiple.value,
  650. [`${prefixCls}-single`]: !multiple.value,
  651. [`${prefixCls}-allow-clear`]: allowClear,
  652. [`${prefixCls}-show-arrow`]: mergedShowArrow,
  653. [`${prefixCls}-disabled`]: disabled,
  654. [`${prefixCls}-loading`]: loading,
  655. [`${prefixCls}-open`]: mergedOpen.value,
  656. [`${prefixCls}-customize-input`]: customizeInputElement,
  657. [`${prefixCls}-show-search`]: mergedShowSearch.value
  658. });
  659. // >>> Selector
  660. const selectorNode = (0, _vue.createVNode)(_SelectTrigger.default, {
  661. "ref": triggerRef,
  662. "disabled": disabled,
  663. "prefixCls": prefixCls,
  664. "visible": triggerOpen.value,
  665. "popupElement": optionList,
  666. "containerWidth": containerWidth.value,
  667. "animation": animation,
  668. "transitionName": transitionName,
  669. "dropdownStyle": dropdownStyle,
  670. "dropdownClassName": dropdownClassName,
  671. "direction": direction,
  672. "dropdownMatchSelectWidth": dropdownMatchSelectWidth,
  673. "dropdownRender": dropdownRender,
  674. "dropdownAlign": dropdownAlign,
  675. "placement": placement,
  676. "getPopupContainer": getPopupContainer,
  677. "empty": emptyOptions,
  678. "getTriggerDOMNode": () => selectorDomRef.current,
  679. "onPopupVisibleChange": onTriggerVisibleChange,
  680. "onPopupMouseEnter": onPopupMouseEnter,
  681. "onPopupFocusin": onPopupFocusin,
  682. "onPopupFocusout": onPopupFocusout
  683. }, {
  684. default: () => {
  685. return customizeRawInputElement ? (0, _propsUtil.isValidElement)(customizeRawInputElement) && (0, _vnode.cloneElement)(customizeRawInputElement, {
  686. ref: selectorDomRef
  687. }, false, true) : (0, _vue.createVNode)(_Selector.default, (0, _objectSpread2.default)((0, _objectSpread2.default)({}, props), {}, {
  688. "domRef": selectorDomRef,
  689. "prefixCls": prefixCls,
  690. "inputElement": customizeInputElement,
  691. "ref": selectorRef,
  692. "id": id,
  693. "showSearch": mergedShowSearch.value,
  694. "mode": mode,
  695. "activeDescendantId": activeDescendantId,
  696. "tagRender": tagRender,
  697. "optionLabelRender": optionLabelRender,
  698. "values": displayValues,
  699. "open": mergedOpen.value,
  700. "onToggleOpen": onToggleOpen,
  701. "activeValue": activeValue,
  702. "searchValue": mergedSearchValue.value,
  703. "onSearch": onInternalSearch,
  704. "onSearchSubmit": onInternalSearchSubmit,
  705. "onRemove": onSelectorRemove,
  706. "tokenWithEnter": tokenWithEnter.value
  707. }), null);
  708. }
  709. });
  710. // >>> Render
  711. let renderNode;
  712. // Render raw
  713. if (customizeRawInputElement) {
  714. renderNode = selectorNode;
  715. } else {
  716. renderNode = (0, _vue.createVNode)("div", (0, _objectSpread2.default)((0, _objectSpread2.default)({}, domProps), {}, {
  717. "class": mergedClassName,
  718. "ref": containerRef,
  719. "onMousedown": onInternalMouseDown,
  720. "onKeydown": onInternalKeyDown,
  721. "onKeyup": onInternalKeyUp
  722. }), [mockFocused.value && !mergedOpen.value && (0, _vue.createVNode)("span", {
  723. "style": {
  724. width: 0,
  725. height: 0,
  726. position: 'absolute',
  727. overflow: 'hidden',
  728. opacity: 0
  729. },
  730. "aria-live": "polite"
  731. }, [`${displayValues.map(_ref2 => {
  732. let {
  733. label,
  734. value
  735. } = _ref2;
  736. return ['number', 'string'].includes(typeof label) ? label : value;
  737. }).join(', ')}`]), selectorNode, arrowNode, clearNode]);
  738. }
  739. return renderNode;
  740. };
  741. }
  742. });