combobox.js 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405
  1. /*!
  2. * All material copyright ESRI, All Rights Reserved, unless otherwise specified.
  3. * See https://github.com/Esri/calcite-components/blob/master/LICENSE.md for details.
  4. * v1.0.0-beta.97
  5. */
  6. import { h, Host } from "@stencil/core";
  7. import { filter } from "../../utils/filter";
  8. import { debounce } from "lodash-es";
  9. import { FloatingCSS, connectFloatingUI, disconnectFloatingUI, defaultMenuPlacement, filterComputedPlacements, reposition, updateAfterClose } from "../../utils/floating-ui";
  10. import { guid } from "../../utils/guid";
  11. import { ComboboxChildSelector, ComboboxItem, ComboboxItemGroup, TEXT } from "./resources";
  12. import { getItemAncestors, getItemChildren, hasActiveChildren } from "./utils";
  13. import { connectLabel, disconnectLabel, getLabelText } from "../../utils/label";
  14. import { afterConnectDefaultValueSet, connectForm, disconnectForm, HiddenFormInputSlot, submitForm } from "../../utils/form";
  15. import { createObserver } from "../../utils/observers";
  16. import { updateHostInteraction } from "../../utils/interactive";
  17. import { isPrimaryPointerButton, toAriaBoolean } from "../../utils/dom";
  18. import { connectOpenCloseComponent, disconnectOpenCloseComponent } from "../../utils/openCloseComponent";
  19. const isGroup = (el) => el.tagName === ComboboxItemGroup;
  20. const itemUidPrefix = "combobox-item-";
  21. const chipUidPrefix = "combobox-chip-";
  22. const labelUidPrefix = "combobox-label-";
  23. const listboxUidPrefix = "combobox-listbox-";
  24. const inputUidPrefix = "combobox-input-";
  25. /**
  26. * @slot - A slot for adding `calcite-combobox-item`s.
  27. */
  28. export class Combobox {
  29. constructor() {
  30. //--------------------------------------------------------------------------
  31. //
  32. // Public Properties
  33. //
  34. //--------------------------------------------------------------------------
  35. /**
  36. * When `true`, displays and positions the component.
  37. *
  38. * @deprecated use `open` instead.
  39. */
  40. this.active = false;
  41. /**When `true`, displays and positions the component. */
  42. this.open = false;
  43. /** When `true`, interaction is prevented and the component is displayed with lower opacity. */
  44. this.disabled = false;
  45. /** Specifies the maximum number of `calcite-combobox-item`s (including nested children) to display before displaying a scrollbar. */
  46. this.maxItems = 0;
  47. /**
  48. * Determines the type of positioning to use for the overlaid content.
  49. *
  50. * Using `"absolute"` will work for most cases. The component will be positioned inside of overflowing parent containers and will affect the container's layout.
  51. *
  52. * `"fixed"` should be used to escape an overflowing parent container, or when the reference element's `position` CSS property is `"fixed"`.
  53. *
  54. */
  55. this.overlayPositioning = "absolute";
  56. /**
  57. * When `true`, the component must have a value in order for the form to submit.
  58. *
  59. * @internal
  60. */
  61. this.required = false;
  62. /**
  63. * Specifies the selection mode -
  64. * `"multi"` (allow any number of selected items),
  65. * `"single"` (allow only one selection), or
  66. * `"ancestors"` (like `"multi"`, but show ancestors of selected items as selected. Only the deepest children are shown in `calcite-chip`s).
  67. */
  68. this.selectionMode = "multi";
  69. /** Specifies the size of the component. */
  70. this.scale = "m";
  71. /** The component's value(s) from the selected `calcite-combobox-item`(s). */
  72. this.value = null;
  73. /**
  74. * Accessible name for the component's remove tag when a `calcite-combobox-item` is selected.
  75. *
  76. * @default "Remove tag"
  77. */
  78. this.intlRemoveTag = TEXT.removeTag;
  79. //--------------------------------------------------------------------------
  80. //
  81. // Private State/Props
  82. //
  83. //--------------------------------------------------------------------------
  84. this.placement = defaultMenuPlacement;
  85. this.internalValueChangeFlag = false;
  86. this.items = [];
  87. this.groupItems = [];
  88. this.selectedItems = [];
  89. this.visibleItems = [];
  90. this.activeItemIndex = -1;
  91. this.activeChipIndex = -1;
  92. this.activeDescendant = "";
  93. this.text = "";
  94. this.textInput = null;
  95. this.mutationObserver = createObserver("mutation", () => this.updateItems());
  96. this.resizeObserver = createObserver("resize", () => this.setMaxScrollerHeight());
  97. this.guid = guid();
  98. this.inputHeight = 0;
  99. this.ignoreSelectedEventsFlag = false;
  100. this.openTransitionProp = "opacity";
  101. // --------------------------------------------------------------------------
  102. //
  103. // Private Methods
  104. //
  105. // --------------------------------------------------------------------------
  106. this.setFilteredPlacements = () => {
  107. const { el, flipPlacements } = this;
  108. this.filteredFlipPlacements = flipPlacements
  109. ? filterComputedPlacements(flipPlacements, el)
  110. : null;
  111. };
  112. this.getValue = () => {
  113. const items = this.selectedItems.map((item) => { var _a; return (_a = item === null || item === void 0 ? void 0 : item.value) === null || _a === void 0 ? void 0 : _a.toString(); });
  114. return (items === null || items === void 0 ? void 0 : items.length) ? (items.length > 1 ? items : items[0]) : "";
  115. };
  116. this.onLabelClick = () => {
  117. this.setFocus();
  118. };
  119. this.keydownHandler = (event) => {
  120. const { key } = event;
  121. switch (key) {
  122. case "Tab":
  123. this.activeChipIndex = -1;
  124. this.activeItemIndex = -1;
  125. if (this.allowCustomValues && this.text) {
  126. this.addCustomChip(this.text, true);
  127. event.preventDefault();
  128. }
  129. else if (this.open) {
  130. this.open = false;
  131. event.preventDefault();
  132. }
  133. break;
  134. case "ArrowLeft":
  135. this.previousChip();
  136. event.preventDefault();
  137. break;
  138. case "ArrowRight":
  139. this.nextChip();
  140. event.preventDefault();
  141. break;
  142. case "ArrowUp":
  143. event.preventDefault();
  144. this.shiftActiveItemIndex(-1);
  145. if (!this.comboboxInViewport()) {
  146. this.el.scrollIntoView();
  147. }
  148. break;
  149. case "ArrowDown":
  150. event.preventDefault();
  151. if (!this.open) {
  152. this.open = true;
  153. }
  154. this.shiftActiveItemIndex(1);
  155. if (!this.comboboxInViewport()) {
  156. this.el.scrollIntoView();
  157. }
  158. break;
  159. case " ":
  160. if (!this.textInput.value) {
  161. event.preventDefault();
  162. this.open = true;
  163. this.shiftActiveItemIndex(1);
  164. }
  165. break;
  166. case "Home":
  167. if (!this.open) {
  168. return;
  169. }
  170. event.preventDefault();
  171. this.updateActiveItemIndex(0);
  172. this.scrollToActiveItem();
  173. if (!this.comboboxInViewport()) {
  174. this.el.scrollIntoView();
  175. }
  176. break;
  177. case "End":
  178. if (!this.open) {
  179. return;
  180. }
  181. event.preventDefault();
  182. this.updateActiveItemIndex(this.visibleItems.length - 1);
  183. this.scrollToActiveItem();
  184. if (!this.comboboxInViewport()) {
  185. this.el.scrollIntoView();
  186. }
  187. break;
  188. case "Escape":
  189. this.open = false;
  190. event.preventDefault();
  191. break;
  192. case "Enter":
  193. if (this.activeItemIndex > -1) {
  194. this.toggleSelection(this.visibleItems[this.activeItemIndex]);
  195. event.preventDefault();
  196. }
  197. else if (this.activeChipIndex > -1) {
  198. this.removeActiveChip();
  199. event.preventDefault();
  200. }
  201. else if (this.allowCustomValues && this.text) {
  202. this.addCustomChip(this.text, true);
  203. event.preventDefault();
  204. }
  205. else if (!event.defaultPrevented) {
  206. if (submitForm(this)) {
  207. event.preventDefault();
  208. }
  209. }
  210. break;
  211. case "Delete":
  212. case "Backspace":
  213. if (this.activeChipIndex > -1) {
  214. event.preventDefault();
  215. this.removeActiveChip();
  216. }
  217. else if (!this.text && this.isMulti()) {
  218. event.preventDefault();
  219. this.removeLastChip();
  220. }
  221. break;
  222. }
  223. };
  224. this.toggleCloseEnd = () => {
  225. this.open = false;
  226. this.el.removeEventListener("calciteComboboxClose", this.toggleCloseEnd);
  227. };
  228. this.toggleOpenEnd = () => {
  229. this.open = false;
  230. this.el.removeEventListener("calciteComboboxOpen", this.toggleOpenEnd);
  231. };
  232. this.setMaxScrollerHeight = async () => {
  233. const { listContainerEl, open, referenceEl } = this;
  234. if (!listContainerEl || !open) {
  235. return;
  236. }
  237. await this.reposition(true);
  238. const maxScrollerHeight = this.getMaxScrollerHeight();
  239. listContainerEl.style.maxHeight = maxScrollerHeight > 0 ? `${maxScrollerHeight}px` : "";
  240. listContainerEl.style.minWidth = `${referenceEl.clientWidth}px`;
  241. await this.reposition(true);
  242. };
  243. this.calciteChipDismissHandler = (event, comboboxItem) => {
  244. this.open = false;
  245. const selection = this.items.find((item) => item === comboboxItem);
  246. if (selection) {
  247. this.toggleSelection(selection, false);
  248. }
  249. this.calciteComboboxChipDismiss.emit(event.detail);
  250. };
  251. this.clickHandler = (event) => {
  252. if (event.composedPath().some((node) => node.tagName === "CALCITE-CHIP")) {
  253. return;
  254. }
  255. this.open = !this.open;
  256. this.updateActiveItemIndex(0);
  257. this.setFocus();
  258. };
  259. this.setInactiveIfNotContained = (event) => {
  260. const composedPath = event.composedPath();
  261. if (!this.open || composedPath.includes(this.el) || composedPath.includes(this.referenceEl)) {
  262. return;
  263. }
  264. if (this.allowCustomValues && this.text.trim().length) {
  265. this.addCustomChip(this.text);
  266. }
  267. if (this.selectionMode === "single") {
  268. if (this.textInput) {
  269. this.textInput.value = "";
  270. }
  271. this.text = "";
  272. this.filterItems("");
  273. this.updateActiveItemIndex(-1);
  274. }
  275. this.open = false;
  276. };
  277. this.setFloatingEl = (el) => {
  278. this.floatingEl = el;
  279. connectFloatingUI(this, this.referenceEl, this.floatingEl);
  280. };
  281. this.setContainerEl = (el) => {
  282. this.resizeObserver.observe(el);
  283. this.listContainerEl = el;
  284. this.transitionEl = el;
  285. connectOpenCloseComponent(this);
  286. };
  287. this.setReferenceEl = (el) => {
  288. this.referenceEl = el;
  289. connectFloatingUI(this, this.referenceEl, this.floatingEl);
  290. };
  291. this.inputHandler = (event) => {
  292. const value = event.target.value;
  293. this.text = value;
  294. this.filterItems(value);
  295. if (value) {
  296. this.activeChipIndex = -1;
  297. }
  298. };
  299. this.filterItems = (() => {
  300. const find = (item, filteredData) => item &&
  301. filteredData.some(({ label, value }) => {
  302. if (isGroup(item)) {
  303. return value === item.label;
  304. }
  305. return (value === item.textLabel ||
  306. value === item.value ||
  307. label === item.textLabel ||
  308. label === item.value);
  309. });
  310. return debounce((text) => {
  311. const filteredData = filter(this.data, text);
  312. const items = this.getCombinedItems();
  313. items.forEach((item) => {
  314. const hidden = !find(item, filteredData);
  315. item.hidden = hidden;
  316. const [parent, grandparent] = item.ancestors;
  317. if (find(parent, filteredData) || find(grandparent, filteredData)) {
  318. item.hidden = false;
  319. }
  320. if (!hidden) {
  321. item.ancestors.forEach((ancestor) => (ancestor.hidden = false));
  322. }
  323. });
  324. this.visibleItems = this.getVisibleItems();
  325. this.calciteComboboxFilterChange.emit({ visibleItems: [...this.visibleItems], text: text });
  326. }, 100);
  327. })();
  328. this.internalCalciteLookupChangeEvent = () => {
  329. this.calciteLookupChange.emit(this.selectedItems);
  330. };
  331. this.emitCalciteLookupChange = debounce(this.internalCalciteLookupChangeEvent, 0);
  332. this.internalComboboxChangeEvent = () => {
  333. const { selectedItems } = this;
  334. this.calciteComboboxChange.emit({ selectedItems });
  335. };
  336. this.emitComboboxChange = debounce(this.internalComboboxChangeEvent, 0);
  337. this.updateItems = () => {
  338. this.items = this.getItems();
  339. this.groupItems = this.getGroupItems();
  340. this.data = this.getData();
  341. this.selectedItems = this.getSelectedItems();
  342. this.visibleItems = this.getVisibleItems();
  343. this.needsIcon = this.getNeedsIcon();
  344. if (!this.allowCustomValues) {
  345. this.setMaxScrollerHeight();
  346. }
  347. };
  348. this.scrollToActiveItem = () => {
  349. const activeItem = this.visibleItems[this.activeItemIndex];
  350. const height = this.calculateSingleItemHeight(activeItem);
  351. const { offsetHeight, scrollTop } = this.listContainerEl;
  352. if (offsetHeight + scrollTop < activeItem.offsetTop + height) {
  353. this.listContainerEl.scrollTop = activeItem.offsetTop - offsetHeight + height;
  354. }
  355. else if (activeItem.offsetTop < scrollTop) {
  356. this.listContainerEl.scrollTop = activeItem.offsetTop;
  357. }
  358. };
  359. this.comboboxFocusHandler = () => {
  360. var _a;
  361. (_a = this.textInput) === null || _a === void 0 ? void 0 : _a.focus();
  362. };
  363. this.comboboxBlurHandler = (event) => {
  364. this.setInactiveIfNotContained(event);
  365. };
  366. }
  367. activeHandler(value) {
  368. if (this.disabled) {
  369. this.active = false;
  370. this.open = false;
  371. return;
  372. }
  373. this.open = value;
  374. }
  375. openHandler(value) {
  376. if (!value) {
  377. updateAfterClose(this.floatingEl);
  378. }
  379. if (this.disabled) {
  380. this.active = false;
  381. this.open = false;
  382. return;
  383. }
  384. this.active = value;
  385. this.setMaxScrollerHeight();
  386. }
  387. handleDisabledChange(value) {
  388. if (!value) {
  389. this.active = false;
  390. this.open = false;
  391. }
  392. }
  393. maxItemsHandler() {
  394. this.setMaxScrollerHeight();
  395. }
  396. overlayPositioningHandler() {
  397. this.reposition(true);
  398. }
  399. valueHandler(value) {
  400. if (!this.internalValueChangeFlag) {
  401. const items = this.getItems();
  402. if (Array.isArray(value)) {
  403. items.forEach((item) => (item.selected = value.includes(item.value)));
  404. }
  405. else if (value) {
  406. items.forEach((item) => (item.selected = value === item.value));
  407. }
  408. else {
  409. items.forEach((item) => (item.selected = false));
  410. }
  411. this.updateItems();
  412. }
  413. }
  414. flipPlacementsHandler() {
  415. this.setFilteredPlacements();
  416. this.reposition(true);
  417. }
  418. //--------------------------------------------------------------------------
  419. //
  420. // Event Listeners
  421. //
  422. //--------------------------------------------------------------------------
  423. documentClickHandler(event) {
  424. if (!isPrimaryPointerButton(event)) {
  425. return;
  426. }
  427. this.setInactiveIfNotContained(event);
  428. }
  429. calciteComboboxItemChangeHandler(event) {
  430. if (this.ignoreSelectedEventsFlag) {
  431. return;
  432. }
  433. const target = event.target;
  434. const newIndex = this.visibleItems.indexOf(target);
  435. this.updateActiveItemIndex(newIndex);
  436. this.toggleSelection(target, target.selected);
  437. }
  438. //--------------------------------------------------------------------------
  439. //
  440. // Public Methods
  441. //
  442. //--------------------------------------------------------------------------
  443. /**
  444. * Updates the position of the component.
  445. *
  446. * @param delayed
  447. */
  448. async reposition(delayed = false) {
  449. const { floatingEl, referenceEl, placement, overlayPositioning, filteredFlipPlacements } = this;
  450. return reposition(this, {
  451. floatingEl,
  452. referenceEl,
  453. overlayPositioning,
  454. placement,
  455. flipPlacements: filteredFlipPlacements,
  456. type: "menu"
  457. }, delayed);
  458. }
  459. /** Sets focus on the component. */
  460. async setFocus() {
  461. var _a;
  462. (_a = this.textInput) === null || _a === void 0 ? void 0 : _a.focus();
  463. this.activeChipIndex = -1;
  464. this.activeItemIndex = -1;
  465. }
  466. // --------------------------------------------------------------------------
  467. //
  468. // Lifecycle
  469. //
  470. // --------------------------------------------------------------------------
  471. connectedCallback() {
  472. var _a;
  473. this.internalValueChangeFlag = true;
  474. this.value = this.getValue();
  475. this.internalValueChangeFlag = false;
  476. (_a = this.mutationObserver) === null || _a === void 0 ? void 0 : _a.observe(this.el, { childList: true, subtree: true });
  477. connectLabel(this);
  478. connectForm(this);
  479. connectOpenCloseComponent(this);
  480. this.setFilteredPlacements();
  481. this.reposition(true);
  482. if (this.active) {
  483. this.activeHandler(this.active);
  484. }
  485. if (this.open) {
  486. this.openHandler(this.open);
  487. }
  488. }
  489. componentWillLoad() {
  490. this.updateItems();
  491. }
  492. componentDidLoad() {
  493. afterConnectDefaultValueSet(this, this.getValue());
  494. this.reposition(true);
  495. }
  496. componentDidRender() {
  497. if (this.el.offsetHeight !== this.inputHeight) {
  498. this.reposition(true);
  499. this.inputHeight = this.el.offsetHeight;
  500. }
  501. updateHostInteraction(this);
  502. }
  503. disconnectedCallback() {
  504. var _a, _b;
  505. (_a = this.mutationObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
  506. (_b = this.resizeObserver) === null || _b === void 0 ? void 0 : _b.disconnect();
  507. disconnectLabel(this);
  508. disconnectForm(this);
  509. disconnectFloatingUI(this, this.referenceEl, this.floatingEl);
  510. disconnectOpenCloseComponent(this);
  511. }
  512. selectedItemsHandler() {
  513. this.internalValueChangeFlag = true;
  514. this.value = this.getValue();
  515. this.internalValueChangeFlag = false;
  516. }
  517. /** when search text is cleared, reset active to */
  518. textHandler() {
  519. this.updateActiveItemIndex(-1);
  520. }
  521. comboboxInViewport() {
  522. const bounding = this.el.getBoundingClientRect();
  523. return (bounding.top >= 0 &&
  524. bounding.left >= 0 &&
  525. bounding.right <= (window.innerWidth || document.documentElement.clientWidth) &&
  526. bounding.bottom <= (window.innerHeight || document.documentElement.clientHeight));
  527. }
  528. onBeforeOpen() {
  529. this.calciteComboboxBeforeOpen.emit();
  530. }
  531. onOpen() {
  532. this.calciteComboboxOpen.emit();
  533. }
  534. onBeforeClose() {
  535. this.calciteComboboxBeforeClose.emit();
  536. }
  537. onClose() {
  538. this.calciteComboboxClose.emit();
  539. }
  540. getMaxScrollerHeight() {
  541. const items = this.getCombinedItems().filter((item) => !item.hidden);
  542. const { maxItems } = this;
  543. let itemsToProcess = 0;
  544. let maxScrollerHeight = 0;
  545. if (items.length > maxItems) {
  546. items.forEach((item) => {
  547. if (itemsToProcess < maxItems && maxItems > 0) {
  548. const height = this.calculateSingleItemHeight(item);
  549. if (height > 0) {
  550. maxScrollerHeight += height;
  551. itemsToProcess++;
  552. }
  553. }
  554. });
  555. }
  556. return maxScrollerHeight;
  557. }
  558. calculateSingleItemHeight(item) {
  559. let height = item.offsetHeight;
  560. // if item has children items, don't count their height twice
  561. const children = Array.from(item.querySelectorAll(ComboboxChildSelector));
  562. children
  563. .map((child) => child === null || child === void 0 ? void 0 : child.offsetHeight)
  564. .forEach((offsetHeight) => {
  565. height -= offsetHeight;
  566. });
  567. return height;
  568. }
  569. getCombinedItems() {
  570. return [...this.groupItems, ...this.items];
  571. }
  572. toggleSelection(item, value = !item.selected) {
  573. if (!item) {
  574. return;
  575. }
  576. if (this.isMulti()) {
  577. item.selected = value;
  578. this.updateAncestors(item);
  579. this.selectedItems = this.getSelectedItems();
  580. this.emitCalciteLookupChange();
  581. this.emitComboboxChange();
  582. this.resetText();
  583. this.filterItems("");
  584. }
  585. else {
  586. this.ignoreSelectedEventsFlag = true;
  587. this.items.forEach((el) => (el.selected = el === item ? value : false));
  588. this.ignoreSelectedEventsFlag = false;
  589. this.selectedItems = this.getSelectedItems();
  590. this.emitComboboxChange();
  591. if (this.textInput) {
  592. this.textInput.value = item.textLabel;
  593. }
  594. this.open = false;
  595. this.updateActiveItemIndex(-1);
  596. this.resetText();
  597. this.filterItems("");
  598. }
  599. }
  600. updateAncestors(item) {
  601. if (this.selectionMode !== "ancestors") {
  602. return;
  603. }
  604. const ancestors = getItemAncestors(item);
  605. const children = getItemChildren(item);
  606. if (item.selected) {
  607. ancestors.forEach((el) => {
  608. el.selected = true;
  609. });
  610. }
  611. else {
  612. children.forEach((el) => (el.selected = false));
  613. [...ancestors].forEach((el) => {
  614. if (!hasActiveChildren(el)) {
  615. el.selected = false;
  616. }
  617. });
  618. }
  619. }
  620. getVisibleItems() {
  621. return this.items.filter((item) => !item.hidden);
  622. }
  623. getSelectedItems() {
  624. if (!this.isMulti()) {
  625. const match = this.items.find(({ selected }) => selected);
  626. return match ? [match] : [];
  627. }
  628. return (this.items
  629. .filter((item) => item.selected && (this.selectionMode !== "ancestors" || !hasActiveChildren(item)))
  630. /** Preserve order of entered tags */
  631. .sort((a, b) => {
  632. const aIdx = this.selectedItems.indexOf(a);
  633. const bIdx = this.selectedItems.indexOf(b);
  634. if (aIdx > -1 && bIdx > -1) {
  635. return aIdx - bIdx;
  636. }
  637. return bIdx - aIdx;
  638. }));
  639. }
  640. getData() {
  641. return this.items.map((item) => ({
  642. constant: item.constant,
  643. filterDisabled: item.filterDisabled,
  644. value: item.value,
  645. label: item.textLabel
  646. }));
  647. }
  648. getNeedsIcon() {
  649. return this.selectionMode === "single" && this.items.some((item) => item.icon);
  650. }
  651. resetText() {
  652. if (this.textInput) {
  653. this.textInput.value = "";
  654. }
  655. this.text = "";
  656. }
  657. getItems() {
  658. const items = Array.from(this.el.querySelectorAll(ComboboxItem));
  659. return items.filter((item) => !item.disabled);
  660. }
  661. getGroupItems() {
  662. return Array.from(this.el.querySelectorAll(ComboboxItemGroup));
  663. }
  664. addCustomChip(value, focus) {
  665. const existingItem = this.items.find((el) => el.textLabel === value);
  666. if (existingItem) {
  667. this.toggleSelection(existingItem, true);
  668. }
  669. else {
  670. if (!this.isMulti()) {
  671. this.toggleSelection(this.selectedItems[this.selectedItems.length - 1], false);
  672. }
  673. const item = document.createElement(ComboboxItem);
  674. item.value = value;
  675. item.textLabel = value;
  676. item.selected = true;
  677. this.el.appendChild(item);
  678. this.resetText();
  679. if (focus) {
  680. this.setFocus();
  681. }
  682. this.updateItems();
  683. this.filterItems("");
  684. this.emitCalciteLookupChange();
  685. this.emitComboboxChange();
  686. }
  687. }
  688. removeActiveChip() {
  689. this.toggleSelection(this.selectedItems[this.activeChipIndex], false);
  690. this.setFocus();
  691. }
  692. removeLastChip() {
  693. this.toggleSelection(this.selectedItems[this.selectedItems.length - 1], false);
  694. this.setFocus();
  695. }
  696. previousChip() {
  697. if (this.text) {
  698. return;
  699. }
  700. const length = this.selectedItems.length - 1;
  701. const active = this.activeChipIndex;
  702. this.activeChipIndex = active === -1 ? length : Math.max(active - 1, 0);
  703. this.updateActiveItemIndex(-1);
  704. this.focusChip();
  705. }
  706. nextChip() {
  707. if (this.text || this.activeChipIndex === -1) {
  708. return;
  709. }
  710. const last = this.selectedItems.length - 1;
  711. const newIndex = this.activeChipIndex + 1;
  712. if (newIndex > last) {
  713. this.activeChipIndex = -1;
  714. this.setFocus();
  715. }
  716. else {
  717. this.activeChipIndex = newIndex;
  718. this.focusChip();
  719. }
  720. this.updateActiveItemIndex(-1);
  721. }
  722. focusChip() {
  723. var _a;
  724. const guid = (_a = this.selectedItems[this.activeChipIndex]) === null || _a === void 0 ? void 0 : _a.guid;
  725. const chip = guid
  726. ? this.referenceEl.querySelector(`#${chipUidPrefix}${guid}`)
  727. : null;
  728. chip === null || chip === void 0 ? void 0 : chip.setFocus();
  729. }
  730. shiftActiveItemIndex(delta) {
  731. const { length } = this.visibleItems;
  732. const newIndex = (this.activeItemIndex + length + delta) % length;
  733. this.updateActiveItemIndex(newIndex);
  734. this.scrollToActiveItem();
  735. }
  736. updateActiveItemIndex(index) {
  737. var _a;
  738. this.activeItemIndex = index;
  739. let activeDescendant = null;
  740. this.visibleItems.forEach((el, i) => {
  741. if (i === index) {
  742. el.active = true;
  743. activeDescendant = `${itemUidPrefix}${el.guid}`;
  744. }
  745. else {
  746. el.active = false;
  747. }
  748. });
  749. this.activeDescendant = activeDescendant;
  750. if (this.activeItemIndex > -1) {
  751. this.activeChipIndex = -1;
  752. (_a = this.textInput) === null || _a === void 0 ? void 0 : _a.focus();
  753. }
  754. }
  755. isMulti() {
  756. return this.selectionMode !== "single";
  757. }
  758. //--------------------------------------------------------------------------
  759. //
  760. // Render Methods
  761. //
  762. //--------------------------------------------------------------------------
  763. renderChips() {
  764. const { activeChipIndex, scale, selectionMode, intlRemoveTag } = this;
  765. return this.selectedItems.map((item, i) => {
  766. const chipClasses = {
  767. chip: true,
  768. "chip--active": activeChipIndex === i
  769. };
  770. const ancestors = [...getItemAncestors(item)].reverse();
  771. const pathLabel = [...ancestors, item].map((el) => el.textLabel);
  772. const label = selectionMode !== "ancestors" ? item.textLabel : pathLabel.join(" / ");
  773. return (h("calcite-chip", { class: chipClasses, dismissLabel: intlRemoveTag, dismissible: true, icon: item.icon, id: item.guid ? `${chipUidPrefix}${item.guid}` : null, key: item.textLabel, onCalciteChipDismiss: (event) => this.calciteChipDismissHandler(event, item), scale: scale, title: label, value: item.value }, label));
  774. });
  775. }
  776. renderInput() {
  777. const { guid, active, disabled, placeholder, selectionMode, selectedItems, open } = this;
  778. const single = selectionMode === "single";
  779. const selectedItem = selectedItems[0];
  780. const showLabel = !(open || active) && single && !!selectedItem;
  781. return (h("span", { class: {
  782. "input-wrap": true,
  783. "input-wrap--single": single
  784. } }, showLabel && (h("span", { class: {
  785. label: true,
  786. "label--icon": !!(selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.icon)
  787. }, key: "label" }, selectedItem.textLabel)), h("input", { "aria-activedescendant": this.activeDescendant, "aria-autocomplete": "list", "aria-controls": `${listboxUidPrefix}${guid}`, "aria-label": getLabelText(this), class: {
  788. input: true,
  789. "input--single": true,
  790. "input--transparent": this.activeChipIndex > -1,
  791. "input--hidden": showLabel,
  792. "input--icon": !!this.placeholderIcon
  793. }, disabled: disabled, id: `${inputUidPrefix}${guid}`, key: "input", onBlur: this.comboboxBlurHandler, onFocus: this.comboboxFocusHandler, onInput: this.inputHandler, placeholder: placeholder, ref: (el) => (this.textInput = el), type: "text" })));
  794. }
  795. renderListBoxOptions() {
  796. return this.visibleItems.map((item) => (h("li", { "aria-selected": toAriaBoolean(item.selected), id: item.guid ? `${itemUidPrefix}${item.guid}` : null, role: "option", tabindex: "-1" }, item.textLabel)));
  797. }
  798. renderFloatingUIContainer() {
  799. const { active, setFloatingEl, setContainerEl, open } = this;
  800. const classes = {
  801. "list-container": true,
  802. [FloatingCSS.animation]: true,
  803. [FloatingCSS.animationActive]: open || active
  804. };
  805. return (h("div", { "aria-hidden": "true", class: {
  806. "floating-ui-container": true,
  807. "floating-ui-container--active": open || active
  808. }, ref: setFloatingEl }, h("div", { class: classes, ref: setContainerEl }, h("ul", { class: { list: true, "list--hide": !(open || active) } }, h("slot", null)))));
  809. }
  810. renderIconStart() {
  811. const { selectedItems, placeholderIcon, selectionMode } = this;
  812. const selectedItem = selectedItems[0];
  813. const selectedIcon = selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.icon;
  814. const singleSelectionMode = selectionMode === "single";
  815. const iconAtStart = !this.open && selectedItem
  816. ? !!selectedIcon && singleSelectionMode
  817. : !!this.placeholderIcon && (!selectedItem || singleSelectionMode);
  818. return (iconAtStart && (h("span", { class: "icon-start" }, h("calcite-icon", { class: "selected-icon", icon: !this.open && selectedItem ? selectedIcon : placeholderIcon, scale: "s" }))));
  819. }
  820. renderIconEnd() {
  821. const { active, open } = this;
  822. return (h("span", { class: "icon-end" }, h("calcite-icon", { icon: active || open ? "chevron-up" : "chevron-down", scale: "s" })));
  823. }
  824. render() {
  825. const { active, guid, label, open } = this;
  826. const single = this.selectionMode === "single";
  827. return (h(Host, null, h("div", { "aria-autocomplete": "list", "aria-controls": `${listboxUidPrefix}${guid}`, "aria-expanded": toAriaBoolean(open || active), "aria-haspopup": "listbox", "aria-labelledby": `${labelUidPrefix}${guid}`, "aria-live": "polite", "aria-owns": `${listboxUidPrefix}${guid}`, class: {
  828. wrapper: true,
  829. "wrapper--single": single || !this.selectedItems.length,
  830. "wrapper--active": open || active
  831. }, onClick: this.clickHandler, onKeyDown: this.keydownHandler, ref: this.setReferenceEl, role: "combobox" }, h("div", { class: "grid-input" }, this.renderIconStart(), !single && this.renderChips(), h("label", { class: "screen-readers-only", htmlFor: `${inputUidPrefix}${guid}`, id: `${labelUidPrefix}${guid}` }, label), this.renderInput()), this.renderIconEnd()), h("ul", { "aria-labelledby": `${labelUidPrefix}${guid}`, "aria-multiselectable": "true", class: "screen-readers-only", id: `${listboxUidPrefix}${guid}`, role: "listbox", tabIndex: -1 }, this.renderListBoxOptions()), this.renderFloatingUIContainer(), h(HiddenFormInputSlot, { component: this })));
  832. }
  833. static get is() { return "calcite-combobox"; }
  834. static get encapsulation() { return "shadow"; }
  835. static get originalStyleUrls() {
  836. return {
  837. "$": ["combobox.scss"]
  838. };
  839. }
  840. static get styleUrls() {
  841. return {
  842. "$": ["combobox.css"]
  843. };
  844. }
  845. static get properties() {
  846. return {
  847. "active": {
  848. "type": "boolean",
  849. "mutable": true,
  850. "complexType": {
  851. "original": "boolean",
  852. "resolved": "boolean",
  853. "references": {}
  854. },
  855. "required": false,
  856. "optional": false,
  857. "docs": {
  858. "tags": [{
  859. "name": "deprecated",
  860. "text": "use `open` instead."
  861. }],
  862. "text": "When `true`, displays and positions the component."
  863. },
  864. "attribute": "active",
  865. "reflect": true,
  866. "defaultValue": "false"
  867. },
  868. "open": {
  869. "type": "boolean",
  870. "mutable": true,
  871. "complexType": {
  872. "original": "boolean",
  873. "resolved": "boolean",
  874. "references": {}
  875. },
  876. "required": false,
  877. "optional": false,
  878. "docs": {
  879. "tags": [],
  880. "text": "When `true`, displays and positions the component."
  881. },
  882. "attribute": "open",
  883. "reflect": true,
  884. "defaultValue": "false"
  885. },
  886. "disabled": {
  887. "type": "boolean",
  888. "mutable": false,
  889. "complexType": {
  890. "original": "boolean",
  891. "resolved": "boolean",
  892. "references": {}
  893. },
  894. "required": false,
  895. "optional": false,
  896. "docs": {
  897. "tags": [],
  898. "text": "When `true`, interaction is prevented and the component is displayed with lower opacity."
  899. },
  900. "attribute": "disabled",
  901. "reflect": true,
  902. "defaultValue": "false"
  903. },
  904. "label": {
  905. "type": "string",
  906. "mutable": false,
  907. "complexType": {
  908. "original": "string",
  909. "resolved": "string",
  910. "references": {}
  911. },
  912. "required": true,
  913. "optional": false,
  914. "docs": {
  915. "tags": [],
  916. "text": "Accessible name for the component."
  917. },
  918. "attribute": "label",
  919. "reflect": false
  920. },
  921. "placeholder": {
  922. "type": "string",
  923. "mutable": false,
  924. "complexType": {
  925. "original": "string",
  926. "resolved": "string",
  927. "references": {}
  928. },
  929. "required": false,
  930. "optional": true,
  931. "docs": {
  932. "tags": [],
  933. "text": "Specifies the placeholder text for the input."
  934. },
  935. "attribute": "placeholder",
  936. "reflect": false
  937. },
  938. "placeholderIcon": {
  939. "type": "string",
  940. "mutable": false,
  941. "complexType": {
  942. "original": "string",
  943. "resolved": "string",
  944. "references": {}
  945. },
  946. "required": false,
  947. "optional": true,
  948. "docs": {
  949. "tags": [],
  950. "text": "Specifies the placeholder icon for the input."
  951. },
  952. "attribute": "placeholder-icon",
  953. "reflect": true
  954. },
  955. "maxItems": {
  956. "type": "number",
  957. "mutable": false,
  958. "complexType": {
  959. "original": "number",
  960. "resolved": "number",
  961. "references": {}
  962. },
  963. "required": false,
  964. "optional": false,
  965. "docs": {
  966. "tags": [],
  967. "text": "Specifies the maximum number of `calcite-combobox-item`s (including nested children) to display before displaying a scrollbar."
  968. },
  969. "attribute": "max-items",
  970. "reflect": true,
  971. "defaultValue": "0"
  972. },
  973. "name": {
  974. "type": "string",
  975. "mutable": false,
  976. "complexType": {
  977. "original": "string",
  978. "resolved": "string",
  979. "references": {}
  980. },
  981. "required": false,
  982. "optional": false,
  983. "docs": {
  984. "tags": [],
  985. "text": "Specifies the name of the component on form submission."
  986. },
  987. "attribute": "name",
  988. "reflect": true
  989. },
  990. "allowCustomValues": {
  991. "type": "boolean",
  992. "mutable": false,
  993. "complexType": {
  994. "original": "boolean",
  995. "resolved": "boolean",
  996. "references": {}
  997. },
  998. "required": false,
  999. "optional": false,
  1000. "docs": {
  1001. "tags": [],
  1002. "text": "When `true`, allows entry of custom values, which are not in the original set of items."
  1003. },
  1004. "attribute": "allow-custom-values",
  1005. "reflect": true
  1006. },
  1007. "overlayPositioning": {
  1008. "type": "string",
  1009. "mutable": false,
  1010. "complexType": {
  1011. "original": "OverlayPositioning",
  1012. "resolved": "\"absolute\" | \"fixed\"",
  1013. "references": {
  1014. "OverlayPositioning": {
  1015. "location": "import",
  1016. "path": "../../utils/floating-ui"
  1017. }
  1018. }
  1019. },
  1020. "required": false,
  1021. "optional": false,
  1022. "docs": {
  1023. "tags": [],
  1024. "text": "Determines the type of positioning to use for the overlaid content.\n\nUsing `\"absolute\"` will work for most cases. The component will be positioned inside of overflowing parent containers and will affect the container's layout.\n\n`\"fixed\"` should be used to escape an overflowing parent container, or when the reference element's `position` CSS property is `\"fixed\"`."
  1025. },
  1026. "attribute": "overlay-positioning",
  1027. "reflect": true,
  1028. "defaultValue": "\"absolute\""
  1029. },
  1030. "required": {
  1031. "type": "boolean",
  1032. "mutable": false,
  1033. "complexType": {
  1034. "original": "boolean",
  1035. "resolved": "boolean",
  1036. "references": {}
  1037. },
  1038. "required": false,
  1039. "optional": false,
  1040. "docs": {
  1041. "tags": [{
  1042. "name": "internal",
  1043. "text": undefined
  1044. }],
  1045. "text": "When `true`, the component must have a value in order for the form to submit."
  1046. },
  1047. "attribute": "required",
  1048. "reflect": true,
  1049. "defaultValue": "false"
  1050. },
  1051. "selectionMode": {
  1052. "type": "string",
  1053. "mutable": false,
  1054. "complexType": {
  1055. "original": "ComboboxSelectionMode",
  1056. "resolved": "\"ancestors\" | \"multi\" | \"single\"",
  1057. "references": {
  1058. "ComboboxSelectionMode": {
  1059. "location": "import",
  1060. "path": "./interfaces"
  1061. }
  1062. }
  1063. },
  1064. "required": false,
  1065. "optional": false,
  1066. "docs": {
  1067. "tags": [],
  1068. "text": "Specifies the selection mode -\n`\"multi\"` (allow any number of selected items),\n`\"single\"` (allow only one selection), or\n`\"ancestors\"` (like `\"multi\"`, but show ancestors of selected items as selected. Only the deepest children are shown in `calcite-chip`s)."
  1069. },
  1070. "attribute": "selection-mode",
  1071. "reflect": true,
  1072. "defaultValue": "\"multi\""
  1073. },
  1074. "scale": {
  1075. "type": "string",
  1076. "mutable": false,
  1077. "complexType": {
  1078. "original": "Scale",
  1079. "resolved": "\"l\" | \"m\" | \"s\"",
  1080. "references": {
  1081. "Scale": {
  1082. "location": "import",
  1083. "path": "../interfaces"
  1084. }
  1085. }
  1086. },
  1087. "required": false,
  1088. "optional": false,
  1089. "docs": {
  1090. "tags": [],
  1091. "text": "Specifies the size of the component."
  1092. },
  1093. "attribute": "scale",
  1094. "reflect": true,
  1095. "defaultValue": "\"m\""
  1096. },
  1097. "value": {
  1098. "type": "string",
  1099. "mutable": true,
  1100. "complexType": {
  1101. "original": "string | string[]",
  1102. "resolved": "string | string[]",
  1103. "references": {}
  1104. },
  1105. "required": false,
  1106. "optional": false,
  1107. "docs": {
  1108. "tags": [],
  1109. "text": "The component's value(s) from the selected `calcite-combobox-item`(s)."
  1110. },
  1111. "attribute": "value",
  1112. "reflect": false,
  1113. "defaultValue": "null"
  1114. },
  1115. "intlRemoveTag": {
  1116. "type": "string",
  1117. "mutable": false,
  1118. "complexType": {
  1119. "original": "string",
  1120. "resolved": "string",
  1121. "references": {}
  1122. },
  1123. "required": false,
  1124. "optional": false,
  1125. "docs": {
  1126. "tags": [{
  1127. "name": "default",
  1128. "text": "\"Remove tag\""
  1129. }],
  1130. "text": "Accessible name for the component's remove tag when a `calcite-combobox-item` is selected."
  1131. },
  1132. "attribute": "intl-remove-tag",
  1133. "reflect": false,
  1134. "defaultValue": "TEXT.removeTag"
  1135. },
  1136. "flipPlacements": {
  1137. "type": "unknown",
  1138. "mutable": false,
  1139. "complexType": {
  1140. "original": "EffectivePlacement[]",
  1141. "resolved": "Placement[]",
  1142. "references": {
  1143. "EffectivePlacement": {
  1144. "location": "import",
  1145. "path": "../../utils/floating-ui"
  1146. }
  1147. }
  1148. },
  1149. "required": false,
  1150. "optional": true,
  1151. "docs": {
  1152. "tags": [],
  1153. "text": "Defines the available placements that can be used when a flip occurs."
  1154. }
  1155. }
  1156. };
  1157. }
  1158. static get states() {
  1159. return {
  1160. "items": {},
  1161. "groupItems": {},
  1162. "selectedItems": {},
  1163. "visibleItems": {},
  1164. "needsIcon": {},
  1165. "activeItemIndex": {},
  1166. "activeChipIndex": {},
  1167. "activeDescendant": {},
  1168. "text": {}
  1169. };
  1170. }
  1171. static get events() {
  1172. return [{
  1173. "method": "calciteLookupChange",
  1174. "name": "calciteLookupChange",
  1175. "bubbles": true,
  1176. "cancelable": false,
  1177. "composed": true,
  1178. "docs": {
  1179. "tags": [{
  1180. "name": "deprecated",
  1181. "text": "use `calciteComboboxChange` instead."
  1182. }],
  1183. "text": "Fires when the selected items set changes."
  1184. },
  1185. "complexType": {
  1186. "original": "HTMLCalciteComboboxItemElement[]",
  1187. "resolved": "HTMLCalciteComboboxItemElement[]",
  1188. "references": {
  1189. "HTMLCalciteComboboxItemElement": {
  1190. "location": "global"
  1191. }
  1192. }
  1193. }
  1194. }, {
  1195. "method": "calciteComboboxChange",
  1196. "name": "calciteComboboxChange",
  1197. "bubbles": true,
  1198. "cancelable": false,
  1199. "composed": true,
  1200. "docs": {
  1201. "tags": [],
  1202. "text": "Fires when the selected item(s) changes."
  1203. },
  1204. "complexType": {
  1205. "original": "{\n selectedItems: HTMLCalciteComboboxItemElement[];\n }",
  1206. "resolved": "{ selectedItems: HTMLCalciteComboboxItemElement[]; }",
  1207. "references": {
  1208. "HTMLCalciteComboboxItemElement": {
  1209. "location": "global"
  1210. }
  1211. }
  1212. }
  1213. }, {
  1214. "method": "calciteComboboxFilterChange",
  1215. "name": "calciteComboboxFilterChange",
  1216. "bubbles": true,
  1217. "cancelable": false,
  1218. "composed": true,
  1219. "docs": {
  1220. "tags": [],
  1221. "text": "Fires when text is added to filter the options list."
  1222. },
  1223. "complexType": {
  1224. "original": "{\n visibleItems: HTMLCalciteComboboxItemElement[];\n text: string;\n }",
  1225. "resolved": "{ visibleItems: HTMLCalciteComboboxItemElement[]; text: string; }",
  1226. "references": {
  1227. "HTMLCalciteComboboxItemElement": {
  1228. "location": "global"
  1229. }
  1230. }
  1231. }
  1232. }, {
  1233. "method": "calciteComboboxChipDismiss",
  1234. "name": "calciteComboboxChipDismiss",
  1235. "bubbles": true,
  1236. "cancelable": false,
  1237. "composed": true,
  1238. "docs": {
  1239. "tags": [],
  1240. "text": "Fires when a selected item in the component is dismissed via its `calcite-chip`.\n\n**Note:**: The event payload is deprecated, please use the `value` property on the component to determine the removed value instead."
  1241. },
  1242. "complexType": {
  1243. "original": "DeprecatedEventPayload",
  1244. "resolved": "any",
  1245. "references": {
  1246. "DeprecatedEventPayload": {
  1247. "location": "import",
  1248. "path": "../interfaces"
  1249. }
  1250. }
  1251. }
  1252. }, {
  1253. "method": "calciteComboboxBeforeClose",
  1254. "name": "calciteComboboxBeforeClose",
  1255. "bubbles": true,
  1256. "cancelable": false,
  1257. "composed": true,
  1258. "docs": {
  1259. "tags": [],
  1260. "text": "Fires when the component is requested to be closed, and before the closing transition begins."
  1261. },
  1262. "complexType": {
  1263. "original": "void",
  1264. "resolved": "void",
  1265. "references": {}
  1266. }
  1267. }, {
  1268. "method": "calciteComboboxClose",
  1269. "name": "calciteComboboxClose",
  1270. "bubbles": true,
  1271. "cancelable": false,
  1272. "composed": true,
  1273. "docs": {
  1274. "tags": [],
  1275. "text": "Fires when the component is closed and animation is complete."
  1276. },
  1277. "complexType": {
  1278. "original": "void",
  1279. "resolved": "void",
  1280. "references": {}
  1281. }
  1282. }, {
  1283. "method": "calciteComboboxBeforeOpen",
  1284. "name": "calciteComboboxBeforeOpen",
  1285. "bubbles": true,
  1286. "cancelable": false,
  1287. "composed": true,
  1288. "docs": {
  1289. "tags": [],
  1290. "text": "Fires when the component is added to the DOM but not rendered, and before the opening transition begins."
  1291. },
  1292. "complexType": {
  1293. "original": "void",
  1294. "resolved": "void",
  1295. "references": {}
  1296. }
  1297. }, {
  1298. "method": "calciteComboboxOpen",
  1299. "name": "calciteComboboxOpen",
  1300. "bubbles": true,
  1301. "cancelable": false,
  1302. "composed": true,
  1303. "docs": {
  1304. "tags": [],
  1305. "text": "Fires when the component is open and animation is complete."
  1306. },
  1307. "complexType": {
  1308. "original": "void",
  1309. "resolved": "void",
  1310. "references": {}
  1311. }
  1312. }];
  1313. }
  1314. static get methods() {
  1315. return {
  1316. "reposition": {
  1317. "complexType": {
  1318. "signature": "(delayed?: boolean) => Promise<void>",
  1319. "parameters": [{
  1320. "tags": [{
  1321. "name": "param",
  1322. "text": "delayed"
  1323. }],
  1324. "text": ""
  1325. }],
  1326. "references": {
  1327. "Promise": {
  1328. "location": "global"
  1329. }
  1330. },
  1331. "return": "Promise<void>"
  1332. },
  1333. "docs": {
  1334. "text": "Updates the position of the component.",
  1335. "tags": [{
  1336. "name": "param",
  1337. "text": "delayed"
  1338. }]
  1339. }
  1340. },
  1341. "setFocus": {
  1342. "complexType": {
  1343. "signature": "() => Promise<void>",
  1344. "parameters": [],
  1345. "references": {
  1346. "Promise": {
  1347. "location": "global"
  1348. }
  1349. },
  1350. "return": "Promise<void>"
  1351. },
  1352. "docs": {
  1353. "text": "Sets focus on the component.",
  1354. "tags": []
  1355. }
  1356. }
  1357. };
  1358. }
  1359. static get elementRef() { return "el"; }
  1360. static get watchers() {
  1361. return [{
  1362. "propName": "active",
  1363. "methodName": "activeHandler"
  1364. }, {
  1365. "propName": "open",
  1366. "methodName": "openHandler"
  1367. }, {
  1368. "propName": "disabled",
  1369. "methodName": "handleDisabledChange"
  1370. }, {
  1371. "propName": "maxItems",
  1372. "methodName": "maxItemsHandler"
  1373. }, {
  1374. "propName": "overlayPositioning",
  1375. "methodName": "overlayPositioningHandler"
  1376. }, {
  1377. "propName": "value",
  1378. "methodName": "valueHandler"
  1379. }, {
  1380. "propName": "flipPlacements",
  1381. "methodName": "flipPlacementsHandler"
  1382. }, {
  1383. "propName": "selectedItems",
  1384. "methodName": "selectedItemsHandler"
  1385. }, {
  1386. "propName": "text",
  1387. "methodName": "textHandler"
  1388. }];
  1389. }
  1390. static get listeners() {
  1391. return [{
  1392. "name": "pointerdown",
  1393. "method": "documentClickHandler",
  1394. "target": "document",
  1395. "capture": false,
  1396. "passive": true
  1397. }, {
  1398. "name": "calciteComboboxItemChange",
  1399. "method": "calciteComboboxItemChangeHandler",
  1400. "target": undefined,
  1401. "capture": false,
  1402. "passive": false
  1403. }];
  1404. }
  1405. }