useSelect.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', { value: true });
  3. var vue = require('vue');
  4. var shared = require('@vue/shared');
  5. var lodashUnified = require('lodash-unified');
  6. var core = require('@vueuse/core');
  7. require('../../../constants/index.js');
  8. require('../../../utils/index.js');
  9. require('../../../hooks/index.js');
  10. var index = require('../../../hooks/use-locale/index.js');
  11. var index$1 = require('../../../hooks/use-namespace/index.js');
  12. var index$2 = require('../../../hooks/use-deprecated/index.js');
  13. var index$3 = require('../../../hooks/use-form-item/index.js');
  14. var index$4 = require('../../../hooks/use-common-props/index.js');
  15. var error = require('../../../utils/error.js');
  16. var size = require('../../../utils/vue/size.js');
  17. var event = require('../../../constants/event.js');
  18. var scroll = require('../../../utils/dom/scroll.js');
  19. var aria = require('../../../constants/aria.js');
  20. var i18n = require('../../../utils/i18n.js');
  21. function useSelectStates(props) {
  22. const { t } = index.useLocale();
  23. return vue.reactive({
  24. options: /* @__PURE__ */ new Map(),
  25. cachedOptions: /* @__PURE__ */ new Map(),
  26. createdLabel: null,
  27. createdSelected: false,
  28. selected: props.multiple ? [] : {},
  29. inputLength: 20,
  30. inputWidth: 0,
  31. optionsCount: 0,
  32. filteredOptionsCount: 0,
  33. visible: false,
  34. softFocus: false,
  35. selectedLabel: "",
  36. hoverIndex: -1,
  37. query: "",
  38. previousQuery: null,
  39. inputHovering: false,
  40. cachedPlaceHolder: "",
  41. currentPlaceholder: t("el.select.placeholder"),
  42. menuVisibleOnFocus: false,
  43. isOnComposition: false,
  44. isSilentBlur: false,
  45. prefixWidth: 11,
  46. tagInMultiLine: false,
  47. mouseEnter: false
  48. });
  49. }
  50. const useSelect = (props, states, ctx) => {
  51. const { t } = index.useLocale();
  52. const ns = index$1.useNamespace("select");
  53. index$2.useDeprecated({
  54. from: "suffixTransition",
  55. replacement: "override style scheme",
  56. version: "2.3.0",
  57. scope: "props",
  58. ref: "https://element-plus.org/en-US/component/select.html#select-attributes"
  59. }, vue.computed(() => props.suffixTransition === false));
  60. const reference = vue.ref(null);
  61. const input = vue.ref(null);
  62. const tooltipRef = vue.ref(null);
  63. const tags = vue.ref(null);
  64. const selectWrapper = vue.ref(null);
  65. const scrollbar = vue.ref(null);
  66. const hoverOption = vue.ref(-1);
  67. const queryChange = vue.shallowRef({ query: "" });
  68. const groupQueryChange = vue.shallowRef("");
  69. const { form, formItem } = index$3.useFormItem();
  70. const readonly = vue.computed(() => !props.filterable || props.multiple || !states.visible);
  71. const selectDisabled = vue.computed(() => props.disabled || (form == null ? void 0 : form.disabled));
  72. const showClose = vue.computed(() => {
  73. const hasValue = props.multiple ? Array.isArray(props.modelValue) && props.modelValue.length > 0 : props.modelValue !== void 0 && props.modelValue !== null && props.modelValue !== "";
  74. const criteria = props.clearable && !selectDisabled.value && states.inputHovering && hasValue;
  75. return criteria;
  76. });
  77. const iconComponent = vue.computed(() => props.remote && props.filterable && !props.remoteShowSuffix ? "" : props.suffixIcon);
  78. const iconReverse = vue.computed(() => ns.is("reverse", iconComponent.value && states.visible && props.suffixTransition));
  79. const debounce = vue.computed(() => props.remote ? 300 : 0);
  80. const emptyText = vue.computed(() => {
  81. if (props.loading) {
  82. return props.loadingText || t("el.select.loading");
  83. } else {
  84. if (props.remote && states.query === "" && states.options.size === 0)
  85. return false;
  86. if (props.filterable && states.query && states.options.size > 0 && states.filteredOptionsCount === 0) {
  87. return props.noMatchText || t("el.select.noMatch");
  88. }
  89. if (states.options.size === 0) {
  90. return props.noDataText || t("el.select.noData");
  91. }
  92. }
  93. return null;
  94. });
  95. const optionsArray = vue.computed(() => Array.from(states.options.values()));
  96. const cachedOptionsArray = vue.computed(() => Array.from(states.cachedOptions.values()));
  97. const showNewOption = vue.computed(() => {
  98. const hasExistingOption = optionsArray.value.filter((option) => {
  99. return !option.created;
  100. }).some((option) => {
  101. return option.currentLabel === states.query;
  102. });
  103. return props.filterable && props.allowCreate && states.query !== "" && !hasExistingOption;
  104. });
  105. const selectSize = index$4.useSize();
  106. const collapseTagSize = vue.computed(() => ["small"].includes(selectSize.value) ? "small" : "default");
  107. const dropMenuVisible = vue.computed({
  108. get() {
  109. return states.visible && emptyText.value !== false;
  110. },
  111. set(val) {
  112. states.visible = val;
  113. }
  114. });
  115. vue.watch([() => selectDisabled.value, () => selectSize.value, () => form == null ? void 0 : form.size], () => {
  116. vue.nextTick(() => {
  117. resetInputHeight();
  118. });
  119. });
  120. vue.watch(() => props.placeholder, (val) => {
  121. states.cachedPlaceHolder = states.currentPlaceholder = val;
  122. });
  123. vue.watch(() => props.modelValue, (val, oldVal) => {
  124. if (props.multiple) {
  125. resetInputHeight();
  126. if (val && val.length > 0 || input.value && states.query !== "") {
  127. states.currentPlaceholder = "";
  128. } else {
  129. states.currentPlaceholder = states.cachedPlaceHolder;
  130. }
  131. if (props.filterable && !props.reserveKeyword) {
  132. states.query = "";
  133. handleQueryChange(states.query);
  134. }
  135. }
  136. setSelected();
  137. if (props.filterable && !props.multiple) {
  138. states.inputLength = 20;
  139. }
  140. if (!lodashUnified.isEqual(val, oldVal) && props.validateEvent) {
  141. formItem == null ? void 0 : formItem.validate("change").catch((err) => error.debugWarn(err));
  142. }
  143. }, {
  144. flush: "post",
  145. deep: true
  146. });
  147. vue.watch(() => states.visible, (val) => {
  148. var _a, _b, _c;
  149. if (!val) {
  150. if (props.filterable) {
  151. if (shared.isFunction(props.filterMethod)) {
  152. props.filterMethod("");
  153. }
  154. if (shared.isFunction(props.remoteMethod)) {
  155. props.remoteMethod("");
  156. }
  157. }
  158. input.value && input.value.blur();
  159. states.query = "";
  160. states.previousQuery = null;
  161. states.selectedLabel = "";
  162. states.inputLength = 20;
  163. states.menuVisibleOnFocus = false;
  164. resetHoverIndex();
  165. vue.nextTick(() => {
  166. if (input.value && input.value.value === "" && states.selected.length === 0) {
  167. states.currentPlaceholder = states.cachedPlaceHolder;
  168. }
  169. });
  170. if (!props.multiple) {
  171. if (states.selected) {
  172. if (props.filterable && props.allowCreate && states.createdSelected && states.createdLabel) {
  173. states.selectedLabel = states.createdLabel;
  174. } else {
  175. states.selectedLabel = states.selected.currentLabel;
  176. }
  177. if (props.filterable)
  178. states.query = states.selectedLabel;
  179. }
  180. if (props.filterable) {
  181. states.currentPlaceholder = states.cachedPlaceHolder;
  182. }
  183. }
  184. } else {
  185. (_b = (_a = tooltipRef.value) == null ? void 0 : _a.updatePopper) == null ? void 0 : _b.call(_a);
  186. if (props.filterable) {
  187. states.filteredOptionsCount = states.optionsCount;
  188. states.query = props.remote ? "" : states.selectedLabel;
  189. if (props.multiple) {
  190. (_c = input.value) == null ? void 0 : _c.focus();
  191. } else {
  192. if (states.selectedLabel) {
  193. states.currentPlaceholder = `${states.selectedLabel}`;
  194. states.selectedLabel = "";
  195. }
  196. }
  197. handleQueryChange(states.query);
  198. if (!props.multiple && !props.remote) {
  199. queryChange.value.query = "";
  200. vue.triggerRef(queryChange);
  201. vue.triggerRef(groupQueryChange);
  202. }
  203. }
  204. }
  205. ctx.emit("visible-change", val);
  206. });
  207. vue.watch(() => states.options.entries(), () => {
  208. var _a, _b, _c;
  209. if (!core.isClient)
  210. return;
  211. (_b = (_a = tooltipRef.value) == null ? void 0 : _a.updatePopper) == null ? void 0 : _b.call(_a);
  212. if (props.multiple) {
  213. resetInputHeight();
  214. }
  215. const inputs = ((_c = selectWrapper.value) == null ? void 0 : _c.querySelectorAll("input")) || [];
  216. if (!Array.from(inputs).includes(document.activeElement)) {
  217. setSelected();
  218. }
  219. if (props.defaultFirstOption && (props.filterable || props.remote) && states.filteredOptionsCount) {
  220. checkDefaultFirstOption();
  221. }
  222. }, {
  223. flush: "post"
  224. });
  225. vue.watch(() => states.hoverIndex, (val) => {
  226. if (core.isNumber(val) && val > -1) {
  227. hoverOption.value = optionsArray.value[val] || {};
  228. } else {
  229. hoverOption.value = {};
  230. }
  231. optionsArray.value.forEach((option) => {
  232. option.hover = hoverOption.value === option;
  233. });
  234. });
  235. const resetInputHeight = () => {
  236. if (props.collapseTags && !props.filterable)
  237. return;
  238. vue.nextTick(() => {
  239. var _a, _b;
  240. if (!reference.value)
  241. return;
  242. const input2 = reference.value.$el.querySelector("input");
  243. const _tags = tags.value;
  244. const sizeInMap = size.getComponentSize(selectSize.value || (form == null ? void 0 : form.size));
  245. input2.style.height = `${(states.selected.length === 0 ? sizeInMap : Math.max(_tags ? _tags.clientHeight + (_tags.clientHeight > sizeInMap ? 6 : 0) : 0, sizeInMap)) - 2}px`;
  246. states.tagInMultiLine = Number.parseFloat(input2.style.height) >= sizeInMap;
  247. if (states.visible && emptyText.value !== false) {
  248. (_b = (_a = tooltipRef.value) == null ? void 0 : _a.updatePopper) == null ? void 0 : _b.call(_a);
  249. }
  250. });
  251. };
  252. const handleQueryChange = async (val) => {
  253. if (states.previousQuery === val || states.isOnComposition)
  254. return;
  255. if (states.previousQuery === null && (shared.isFunction(props.filterMethod) || shared.isFunction(props.remoteMethod))) {
  256. states.previousQuery = val;
  257. return;
  258. }
  259. states.previousQuery = val;
  260. vue.nextTick(() => {
  261. var _a, _b;
  262. if (states.visible)
  263. (_b = (_a = tooltipRef.value) == null ? void 0 : _a.updatePopper) == null ? void 0 : _b.call(_a);
  264. });
  265. states.hoverIndex = -1;
  266. if (props.multiple && props.filterable) {
  267. vue.nextTick(() => {
  268. const length = input.value.value.length * 15 + 20;
  269. states.inputLength = props.collapseTags ? Math.min(50, length) : length;
  270. managePlaceholder();
  271. resetInputHeight();
  272. });
  273. }
  274. if (props.remote && shared.isFunction(props.remoteMethod)) {
  275. states.hoverIndex = -1;
  276. props.remoteMethod(val);
  277. } else if (shared.isFunction(props.filterMethod)) {
  278. props.filterMethod(val);
  279. vue.triggerRef(groupQueryChange);
  280. } else {
  281. states.filteredOptionsCount = states.optionsCount;
  282. queryChange.value.query = val;
  283. vue.triggerRef(queryChange);
  284. vue.triggerRef(groupQueryChange);
  285. }
  286. if (props.defaultFirstOption && (props.filterable || props.remote) && states.filteredOptionsCount) {
  287. await vue.nextTick();
  288. checkDefaultFirstOption();
  289. }
  290. };
  291. const managePlaceholder = () => {
  292. if (states.currentPlaceholder !== "") {
  293. states.currentPlaceholder = input.value.value ? "" : states.cachedPlaceHolder;
  294. }
  295. };
  296. const checkDefaultFirstOption = () => {
  297. const optionsInDropdown = optionsArray.value.filter((n) => n.visible && !n.disabled && !n.states.groupDisabled);
  298. const userCreatedOption = optionsInDropdown.find((n) => n.created);
  299. const firstOriginOption = optionsInDropdown[0];
  300. states.hoverIndex = getValueIndex(optionsArray.value, userCreatedOption || firstOriginOption);
  301. };
  302. const setSelected = () => {
  303. var _a;
  304. if (!props.multiple) {
  305. const option = getOption(props.modelValue);
  306. if ((_a = option.props) == null ? void 0 : _a.created) {
  307. states.createdLabel = option.props.value;
  308. states.createdSelected = true;
  309. } else {
  310. states.createdSelected = false;
  311. }
  312. states.selectedLabel = option.currentLabel;
  313. states.selected = option;
  314. if (props.filterable)
  315. states.query = states.selectedLabel;
  316. return;
  317. } else {
  318. states.selectedLabel = "";
  319. }
  320. const result = [];
  321. if (Array.isArray(props.modelValue)) {
  322. props.modelValue.forEach((value) => {
  323. result.push(getOption(value));
  324. });
  325. }
  326. states.selected = result;
  327. vue.nextTick(() => {
  328. resetInputHeight();
  329. });
  330. };
  331. const getOption = (value) => {
  332. let option;
  333. const isObjectValue = shared.toRawType(value).toLowerCase() === "object";
  334. const isNull = shared.toRawType(value).toLowerCase() === "null";
  335. const isUndefined = shared.toRawType(value).toLowerCase() === "undefined";
  336. for (let i = states.cachedOptions.size - 1; i >= 0; i--) {
  337. const cachedOption = cachedOptionsArray.value[i];
  338. const isEqualValue = isObjectValue ? lodashUnified.get(cachedOption.value, props.valueKey) === lodashUnified.get(value, props.valueKey) : cachedOption.value === value;
  339. if (isEqualValue) {
  340. option = {
  341. value,
  342. currentLabel: cachedOption.currentLabel,
  343. isDisabled: cachedOption.isDisabled
  344. };
  345. break;
  346. }
  347. }
  348. if (option)
  349. return option;
  350. const label = isObjectValue ? value.label : !isNull && !isUndefined ? value : "";
  351. const newOption = {
  352. value,
  353. currentLabel: label
  354. };
  355. if (props.multiple) {
  356. ;
  357. newOption.hitState = false;
  358. }
  359. return newOption;
  360. };
  361. const resetHoverIndex = () => {
  362. setTimeout(() => {
  363. const valueKey = props.valueKey;
  364. if (!props.multiple) {
  365. states.hoverIndex = optionsArray.value.findIndex((item) => {
  366. return getValueKey(item) === getValueKey(states.selected);
  367. });
  368. } else {
  369. if (states.selected.length > 0) {
  370. states.hoverIndex = Math.min.apply(null, states.selected.map((selected) => {
  371. return optionsArray.value.findIndex((item) => {
  372. return lodashUnified.get(item, valueKey) === lodashUnified.get(selected, valueKey);
  373. });
  374. }));
  375. } else {
  376. states.hoverIndex = -1;
  377. }
  378. }
  379. }, 300);
  380. };
  381. const handleResize = () => {
  382. var _a, _b;
  383. resetInputWidth();
  384. (_b = (_a = tooltipRef.value) == null ? void 0 : _a.updatePopper) == null ? void 0 : _b.call(_a);
  385. if (props.multiple && !props.filterable)
  386. resetInputHeight();
  387. };
  388. const resetInputWidth = () => {
  389. var _a;
  390. states.inputWidth = (_a = reference.value) == null ? void 0 : _a.$el.getBoundingClientRect().width;
  391. };
  392. const onInputChange = () => {
  393. if (props.filterable && states.query !== states.selectedLabel) {
  394. states.query = states.selectedLabel;
  395. handleQueryChange(states.query);
  396. }
  397. };
  398. const debouncedOnInputChange = lodashUnified.debounce(() => {
  399. onInputChange();
  400. }, debounce.value);
  401. const debouncedQueryChange = lodashUnified.debounce((e) => {
  402. handleQueryChange(e.target.value);
  403. }, debounce.value);
  404. const emitChange = (val) => {
  405. if (!lodashUnified.isEqual(props.modelValue, val)) {
  406. ctx.emit(event.CHANGE_EVENT, val);
  407. }
  408. };
  409. const deletePrevTag = (e) => {
  410. if (e.target.value.length <= 0 && !toggleLastOptionHitState()) {
  411. const value = props.modelValue.slice();
  412. value.pop();
  413. ctx.emit(event.UPDATE_MODEL_EVENT, value);
  414. emitChange(value);
  415. }
  416. if (e.target.value.length === 1 && props.modelValue.length === 0) {
  417. states.currentPlaceholder = states.cachedPlaceHolder;
  418. }
  419. };
  420. const deleteTag = (event$1, tag) => {
  421. const index = states.selected.indexOf(tag);
  422. if (index > -1 && !selectDisabled.value) {
  423. const value = props.modelValue.slice();
  424. value.splice(index, 1);
  425. ctx.emit(event.UPDATE_MODEL_EVENT, value);
  426. emitChange(value);
  427. ctx.emit("remove-tag", tag.value);
  428. }
  429. event$1.stopPropagation();
  430. };
  431. const deleteSelected = (event$1) => {
  432. event$1.stopPropagation();
  433. const value = props.multiple ? [] : "";
  434. if (!shared.isString(value)) {
  435. for (const item of states.selected) {
  436. if (item.isDisabled)
  437. value.push(item.value);
  438. }
  439. }
  440. ctx.emit(event.UPDATE_MODEL_EVENT, value);
  441. emitChange(value);
  442. states.hoverIndex = -1;
  443. states.visible = false;
  444. ctx.emit("clear");
  445. };
  446. const handleOptionSelect = (option, byClick) => {
  447. var _a;
  448. if (props.multiple) {
  449. const value = (props.modelValue || []).slice();
  450. const optionIndex = getValueIndex(value, option.value);
  451. if (optionIndex > -1) {
  452. value.splice(optionIndex, 1);
  453. } else if (props.multipleLimit <= 0 || value.length < props.multipleLimit) {
  454. value.push(option.value);
  455. }
  456. ctx.emit(event.UPDATE_MODEL_EVENT, value);
  457. emitChange(value);
  458. if (option.created) {
  459. states.query = "";
  460. handleQueryChange("");
  461. states.inputLength = 20;
  462. }
  463. if (props.filterable)
  464. (_a = input.value) == null ? void 0 : _a.focus();
  465. } else {
  466. ctx.emit(event.UPDATE_MODEL_EVENT, option.value);
  467. emitChange(option.value);
  468. states.visible = false;
  469. }
  470. states.isSilentBlur = byClick;
  471. setSoftFocus();
  472. if (states.visible)
  473. return;
  474. vue.nextTick(() => {
  475. scrollToOption(option);
  476. });
  477. };
  478. const getValueIndex = (arr = [], value) => {
  479. if (!shared.isObject(value))
  480. return arr.indexOf(value);
  481. const valueKey = props.valueKey;
  482. let index = -1;
  483. arr.some((item, i) => {
  484. if (vue.toRaw(lodashUnified.get(item, valueKey)) === lodashUnified.get(value, valueKey)) {
  485. index = i;
  486. return true;
  487. }
  488. return false;
  489. });
  490. return index;
  491. };
  492. const setSoftFocus = () => {
  493. states.softFocus = true;
  494. const _input = input.value || reference.value;
  495. if (_input) {
  496. _input == null ? void 0 : _input.focus();
  497. }
  498. };
  499. const scrollToOption = (option) => {
  500. var _a, _b, _c, _d, _e;
  501. const targetOption = Array.isArray(option) ? option[0] : option;
  502. let target = null;
  503. if (targetOption == null ? void 0 : targetOption.value) {
  504. const options = optionsArray.value.filter((item) => item.value === targetOption.value);
  505. if (options.length > 0) {
  506. target = options[0].$el;
  507. }
  508. }
  509. if (tooltipRef.value && target) {
  510. const menu = (_d = (_c = (_b = (_a = tooltipRef.value) == null ? void 0 : _a.popperRef) == null ? void 0 : _b.contentRef) == null ? void 0 : _c.querySelector) == null ? void 0 : _d.call(_c, `.${ns.be("dropdown", "wrap")}`);
  511. if (menu) {
  512. scroll.scrollIntoView(menu, target);
  513. }
  514. }
  515. (_e = scrollbar.value) == null ? void 0 : _e.handleScroll();
  516. };
  517. const onOptionCreate = (vm) => {
  518. states.optionsCount++;
  519. states.filteredOptionsCount++;
  520. states.options.set(vm.value, vm);
  521. states.cachedOptions.set(vm.value, vm);
  522. };
  523. const onOptionDestroy = (key, vm) => {
  524. if (states.options.get(key) === vm) {
  525. states.optionsCount--;
  526. states.filteredOptionsCount--;
  527. states.options.delete(key);
  528. }
  529. };
  530. const resetInputState = (e) => {
  531. if (e.code !== aria.EVENT_CODE.backspace)
  532. toggleLastOptionHitState(false);
  533. states.inputLength = input.value.value.length * 15 + 20;
  534. resetInputHeight();
  535. };
  536. const toggleLastOptionHitState = (hit) => {
  537. if (!Array.isArray(states.selected))
  538. return;
  539. const option = states.selected[states.selected.length - 1];
  540. if (!option)
  541. return;
  542. if (hit === true || hit === false) {
  543. option.hitState = hit;
  544. return hit;
  545. }
  546. option.hitState = !option.hitState;
  547. return option.hitState;
  548. };
  549. const handleComposition = (event) => {
  550. const text = event.target.value;
  551. if (event.type === "compositionend") {
  552. states.isOnComposition = false;
  553. vue.nextTick(() => handleQueryChange(text));
  554. } else {
  555. const lastCharacter = text[text.length - 1] || "";
  556. states.isOnComposition = !i18n.isKorean(lastCharacter);
  557. }
  558. };
  559. const handleMenuEnter = () => {
  560. vue.nextTick(() => scrollToOption(states.selected));
  561. };
  562. const handleFocus = (event) => {
  563. if (!states.softFocus) {
  564. if (props.automaticDropdown || props.filterable) {
  565. if (props.filterable && !states.visible) {
  566. states.menuVisibleOnFocus = true;
  567. }
  568. states.visible = true;
  569. }
  570. ctx.emit("focus", event);
  571. } else {
  572. states.softFocus = false;
  573. }
  574. };
  575. const blur = () => {
  576. var _a;
  577. states.visible = false;
  578. (_a = reference.value) == null ? void 0 : _a.blur();
  579. };
  580. const handleBlur = (event) => {
  581. vue.nextTick(() => {
  582. if (states.isSilentBlur) {
  583. states.isSilentBlur = false;
  584. } else {
  585. ctx.emit("blur", event);
  586. }
  587. });
  588. states.softFocus = false;
  589. };
  590. const handleClearClick = (event) => {
  591. deleteSelected(event);
  592. };
  593. const handleClose = () => {
  594. states.visible = false;
  595. };
  596. const handleKeydownEscape = (event) => {
  597. if (states.visible) {
  598. event.preventDefault();
  599. event.stopPropagation();
  600. states.visible = false;
  601. }
  602. };
  603. const toggleMenu = (e) => {
  604. var _a;
  605. if (e && !states.mouseEnter) {
  606. return;
  607. }
  608. if (!selectDisabled.value) {
  609. if (states.menuVisibleOnFocus) {
  610. states.menuVisibleOnFocus = false;
  611. } else {
  612. if (!tooltipRef.value || !tooltipRef.value.isFocusInsideContent()) {
  613. states.visible = !states.visible;
  614. }
  615. }
  616. if (states.visible) {
  617. ;
  618. (_a = input.value || reference.value) == null ? void 0 : _a.focus();
  619. }
  620. }
  621. };
  622. const selectOption = () => {
  623. if (!states.visible) {
  624. toggleMenu();
  625. } else {
  626. if (optionsArray.value[states.hoverIndex]) {
  627. handleOptionSelect(optionsArray.value[states.hoverIndex], void 0);
  628. }
  629. }
  630. };
  631. const getValueKey = (item) => {
  632. return shared.isObject(item.value) ? lodashUnified.get(item.value, props.valueKey) : item.value;
  633. };
  634. const optionsAllDisabled = vue.computed(() => optionsArray.value.filter((option) => option.visible).every((option) => option.disabled));
  635. const navigateOptions = (direction) => {
  636. if (!states.visible) {
  637. states.visible = true;
  638. return;
  639. }
  640. if (states.options.size === 0 || states.filteredOptionsCount === 0)
  641. return;
  642. if (states.isOnComposition)
  643. return;
  644. if (!optionsAllDisabled.value) {
  645. if (direction === "next") {
  646. states.hoverIndex++;
  647. if (states.hoverIndex === states.options.size) {
  648. states.hoverIndex = 0;
  649. }
  650. } else if (direction === "prev") {
  651. states.hoverIndex--;
  652. if (states.hoverIndex < 0) {
  653. states.hoverIndex = states.options.size - 1;
  654. }
  655. }
  656. const option = optionsArray.value[states.hoverIndex];
  657. if (option.disabled === true || option.states.groupDisabled === true || !option.visible) {
  658. navigateOptions(direction);
  659. }
  660. vue.nextTick(() => scrollToOption(hoverOption.value));
  661. }
  662. };
  663. const handleMouseEnter = () => {
  664. states.mouseEnter = true;
  665. };
  666. const handleMouseLeave = () => {
  667. states.mouseEnter = false;
  668. };
  669. return {
  670. optionsArray,
  671. selectSize,
  672. handleResize,
  673. debouncedOnInputChange,
  674. debouncedQueryChange,
  675. deletePrevTag,
  676. deleteTag,
  677. deleteSelected,
  678. handleOptionSelect,
  679. scrollToOption,
  680. readonly,
  681. resetInputHeight,
  682. showClose,
  683. iconComponent,
  684. iconReverse,
  685. showNewOption,
  686. collapseTagSize,
  687. setSelected,
  688. managePlaceholder,
  689. selectDisabled,
  690. emptyText,
  691. toggleLastOptionHitState,
  692. resetInputState,
  693. handleComposition,
  694. onOptionCreate,
  695. onOptionDestroy,
  696. handleMenuEnter,
  697. handleFocus,
  698. blur,
  699. handleBlur,
  700. handleClearClick,
  701. handleClose,
  702. handleKeydownEscape,
  703. toggleMenu,
  704. selectOption,
  705. getValueKey,
  706. navigateOptions,
  707. dropMenuVisible,
  708. queryChange,
  709. groupQueryChange,
  710. reference,
  711. input,
  712. tooltipRef,
  713. tags,
  714. selectWrapper,
  715. scrollbar,
  716. handleMouseEnter,
  717. handleMouseLeave
  718. };
  719. };
  720. exports.useSelect = useSelect;
  721. exports.useSelectStates = useSelectStates;
  722. //# sourceMappingURL=useSelect.js.map