calcite-combobox_3.cjs.entry.js 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059
  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. 'use strict';
  7. Object.defineProperty(exports, '__esModule', { value: true });
  8. const index = require('./index-a0010f96.js');
  9. const filter = require('./filter-9411bbc1.js');
  10. const floatingUi = require('./floating-ui-b48c8256.js');
  11. const guid = require('./guid-f4f03a7a.js');
  12. const dom = require('./dom-2ec8c9ed.js');
  13. const label = require('./label-28060b83.js');
  14. const form = require('./form-1d831023.js');
  15. const observers = require('./observers-5706326b.js');
  16. const interactive = require('./interactive-32293bca.js');
  17. const openCloseComponent = require('./openCloseComponent-178191c0.js');
  18. const debounce = require('./debounce-2c8b61fb.js');
  19. const conditionalSlot = require('./conditionalSlot-ef852d9d.js');
  20. require('./resources-b5a5f8a7.js');
  21. const ComboboxItem$1 = "CALCITE-COMBOBOX-ITEM";
  22. const ComboboxItemGroup$1 = "CALCITE-COMBOBOX-ITEM-GROUP";
  23. const ComboboxChildSelector = `${ComboboxItem$1}, ${ComboboxItemGroup$1}`;
  24. const TEXT = {
  25. removeTag: "Remove tag"
  26. };
  27. function getAncestors(element) {
  28. var _a, _b;
  29. const parent = (_a = element.parentElement) === null || _a === void 0 ? void 0 : _a.closest(ComboboxChildSelector);
  30. const grandparent = (_b = parent === null || parent === void 0 ? void 0 : parent.parentElement) === null || _b === void 0 ? void 0 : _b.closest(ComboboxChildSelector);
  31. return [parent, grandparent].filter((el) => el);
  32. }
  33. function getItemAncestors(item) {
  34. var _a;
  35. return (((_a = item.ancestors) === null || _a === void 0 ? void 0 : _a.filter((el) => el.nodeName === "CALCITE-COMBOBOX-ITEM")) || []);
  36. }
  37. function getItemChildren(item) {
  38. return dom.nodeListToArray(item.querySelectorAll("calcite-combobox-item"));
  39. }
  40. function hasActiveChildren(node) {
  41. const items = dom.nodeListToArray(node.querySelectorAll("calcite-combobox-item"));
  42. return items.filter((item) => item.selected).length > 0;
  43. }
  44. function getDepth(element) {
  45. const result = document.evaluate("ancestor::calcite-combobox-item | ancestor::calcite-combobox-item-group", element, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
  46. return result.snapshotLength;
  47. }
  48. const comboboxCss = "@keyframes in{0%{opacity:0}100%{opacity:1}}@keyframes in-down{0%{opacity:0;transform:translate3D(0, -5px, 0)}100%{opacity:1;transform:translate3D(0, 0, 0)}}@keyframes in-up{0%{opacity:0;transform:translate3D(0, 5px, 0)}100%{opacity:1;transform:translate3D(0, 0, 0)}}@keyframes in-scale{0%{opacity:0;transform:scale3D(0.95, 0.95, 1)}100%{opacity:1;transform:scale3D(1, 1, 1)}}:root{--calcite-animation-timing:calc(150ms * var(--calcite-internal-duration-factor));--calcite-internal-duration-factor:var(--calcite-duration-factor, 1);--calcite-internal-animation-timing-fast:calc(100ms * var(--calcite-internal-duration-factor));--calcite-internal-animation-timing-medium:calc(200ms * var(--calcite-internal-duration-factor));--calcite-internal-animation-timing-slow:calc(300ms * var(--calcite-internal-duration-factor))}.calcite-animate{opacity:0;animation-fill-mode:both;animation-duration:var(--calcite-animation-timing)}.calcite-animate__in{animation-name:in}.calcite-animate__in-down{animation-name:in-down}.calcite-animate__in-up{animation-name:in-up}.calcite-animate__in-scale{animation-name:in-scale}@media (prefers-reduced-motion: reduce){:root{--calcite-internal-duration-factor:0.01}}:root{--calcite-floating-ui-transition:var(--calcite-animation-timing)}:host([hidden]){display:none}:host([disabled]){pointer-events:none;cursor:default;-webkit-user-select:none;user-select:none;opacity:var(--calcite-ui-opacity-disabled)}:host{position:relative;display:block}:host([disabled]) ::slotted([calcite-hydrated][disabled]),:host([disabled]) [calcite-hydrated][disabled]{opacity:1}:host([scale=s]){font-size:var(--calcite-font-size--2);--calcite-combobox-item-spacing-unit-l:0.5rem;--calcite-combobox-item-spacing-unit-s:0.25rem;--calcite-combobox-input-height:1.5rem}:host([scale=m]){font-size:var(--calcite-font-size--1);--calcite-combobox-item-spacing-unit-l:0.75rem;--calcite-combobox-item-spacing-unit-s:0.5rem;--calcite-combobox-input-height:2rem}:host([scale=l]){font-size:var(--calcite-font-size-0);--calcite-combobox-item-spacing-unit-l:1rem;--calcite-combobox-item-spacing-unit-s:0.75rem;--calcite-combobox-input-height:2.75rem}.wrapper{display:flex;border-width:1px;border-style:solid;border-color:var(--calcite-ui-border-input);background-color:var(--calcite-ui-foreground-1);color:var(--calcite-ui-text-1);outline-color:transparent;padding-block:calc(var(--calcite-combobox-item-spacing-unit-s) / 4);padding-inline:var(--calcite-combobox-item-spacing-unit-l)}:host(:focus-within) .wrapper,.wrapper--active{outline:2px solid var(--calcite-ui-brand);outline-offset:-2px}.wrapper--single{padding-block:0;padding-inline:var(--calcite-combobox-item-spacing-unit-l);cursor:pointer;flex-wrap:nowrap}.grid-input{display:flex;flex-grow:1;flex-wrap:wrap;align-items:center;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:0px}.input{flex-grow:1;-webkit-appearance:none;appearance:none;border-style:none;background-color:transparent;padding:0px;font-family:inherit;color:var(--calcite-ui-text-1);font-size:inherit;block-size:var(--calcite-combobox-input-height);line-height:var(--calcite-combobox-input-height);min-inline-size:120px;margin-block-end:var(--calcite-combobox-item-spacing-unit-s)}.input:focus{outline:2px solid transparent;outline-offset:2px}.input--transparent{opacity:0}.input--single{margin-block:0px;padding:0px}.wrapper--active .input-single{cursor:text}.input--hidden{pointer-events:none;inline-size:0px;min-inline-size:0px;opacity:0}.input--icon{padding-block:0;padding-inline:var(--calcite-combobox-item-spacing-unit-l)}.input-wrap{display:flex;flex-grow:1}.input-wrap--single{flex:1 1 0%;overflow:hidden}.label{pointer-events:none;display:flex;max-inline-size:100%;flex:1 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:0px;font-weight:var(--calcite-font-weight-normal);block-size:var(--calcite-combobox-input-height);line-height:var(--calcite-combobox-input-height)}.label--icon{padding-inline:var(--calcite-combobox-item-spacing-unit-l)}.icon-end,.icon-start{display:flex;inline-size:1rem;cursor:pointer;align-items:center}.icon-end{flex:none}.floating-ui-container{display:block;position:absolute;z-index:900;visibility:hidden;pointer-events:none;inline-size:0;block-size:0;overflow:hidden}.floating-ui-container .calcite-floating-ui-anim{position:relative;transition:var(--calcite-floating-ui-transition);visibility:hidden;transition-property:transform, visibility, opacity;opacity:0;box-shadow:0 0 16px 0 rgba(0, 0, 0, 0.16);z-index:1;border-radius:0.25rem}.floating-ui-container[data-placement^=bottom] .calcite-floating-ui-anim{transform:translateY(-5px)}.floating-ui-container[data-placement^=top] .calcite-floating-ui-anim{transform:translateY(5px)}.floating-ui-container[data-placement^=left] .calcite-floating-ui-anim{transform:translateX(5px)}.floating-ui-container[data-placement^=right] .calcite-floating-ui-anim{transform:translateX(-5px)}.floating-ui-container[data-placement] .calcite-floating-ui-anim--active{opacity:1;visibility:visible;transform:translate(0)}.floating-ui-container--active{pointer-events:initial;visibility:visible;inline-size:unset;block-size:unset;overflow:unset}@media (forced-colors: active){.wrapper,.floating-ui-container--active{border:1px solid canvasText}}.screen-readers-only{position:absolute;inline-size:1px;block-size:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0}.list-container{max-block-size:45vh;overflow-y:auto;background-color:var(--calcite-ui-foreground-1);inline-size:var(--calcite-dropdown-width)}.list{margin:0px;display:block;padding:0px}.list--hide{block-size:0px;overflow:hidden}.chip{margin-block:calc(var(--calcite-combobox-item-spacing-unit-s) / 4);margin-inline:0 var(--calcite-combobox-item-spacing-unit-s);max-inline-size:100%}.chip--active{background-color:var(--calcite-ui-foreground-3)}.item{display:block}::slotted(input[slot=hidden-form-input]){margin:0 !important;opacity:0 !important;outline:none !important;padding:0 !important;position:absolute !important;inset:0 !important;transform:none !important;-webkit-appearance:none !important;z-index:-1 !important}";
  49. const isGroup = (el) => el.tagName === ComboboxItemGroup$1;
  50. const itemUidPrefix = "combobox-item-";
  51. const chipUidPrefix = "combobox-chip-";
  52. const labelUidPrefix = "combobox-label-";
  53. const listboxUidPrefix = "combobox-listbox-";
  54. const inputUidPrefix = "combobox-input-";
  55. const Combobox = class {
  56. constructor(hostRef) {
  57. index.registerInstance(this, hostRef);
  58. this.calciteLookupChange = index.createEvent(this, "calciteLookupChange", 6);
  59. this.calciteComboboxChange = index.createEvent(this, "calciteComboboxChange", 6);
  60. this.calciteComboboxFilterChange = index.createEvent(this, "calciteComboboxFilterChange", 6);
  61. this.calciteComboboxChipDismiss = index.createEvent(this, "calciteComboboxChipDismiss", 6);
  62. this.calciteComboboxBeforeClose = index.createEvent(this, "calciteComboboxBeforeClose", 6);
  63. this.calciteComboboxClose = index.createEvent(this, "calciteComboboxClose", 6);
  64. this.calciteComboboxBeforeOpen = index.createEvent(this, "calciteComboboxBeforeOpen", 6);
  65. this.calciteComboboxOpen = index.createEvent(this, "calciteComboboxOpen", 6);
  66. //--------------------------------------------------------------------------
  67. //
  68. // Public Properties
  69. //
  70. //--------------------------------------------------------------------------
  71. /**
  72. * When `true`, displays and positions the component.
  73. *
  74. * @deprecated use `open` instead.
  75. */
  76. this.active = false;
  77. /**When `true`, displays and positions the component. */
  78. this.open = false;
  79. /** When `true`, interaction is prevented and the component is displayed with lower opacity. */
  80. this.disabled = false;
  81. /** Specifies the maximum number of `calcite-combobox-item`s (including nested children) to display before displaying a scrollbar. */
  82. this.maxItems = 0;
  83. /**
  84. * Determines the type of positioning to use for the overlaid content.
  85. *
  86. * Using `"absolute"` will work for most cases. The component will be positioned inside of overflowing parent containers and will affect the container's layout.
  87. *
  88. * `"fixed"` should be used to escape an overflowing parent container, or when the reference element's `position` CSS property is `"fixed"`.
  89. *
  90. */
  91. this.overlayPositioning = "absolute";
  92. /**
  93. * When `true`, the component must have a value in order for the form to submit.
  94. *
  95. * @internal
  96. */
  97. this.required = false;
  98. /**
  99. * Specifies the selection mode -
  100. * `"multi"` (allow any number of selected items),
  101. * `"single"` (allow only one selection), or
  102. * `"ancestors"` (like `"multi"`, but show ancestors of selected items as selected. Only the deepest children are shown in `calcite-chip`s).
  103. */
  104. this.selectionMode = "multi";
  105. /** Specifies the size of the component. */
  106. this.scale = "m";
  107. /** The component's value(s) from the selected `calcite-combobox-item`(s). */
  108. this.value = null;
  109. /**
  110. * Accessible name for the component's remove tag when a `calcite-combobox-item` is selected.
  111. *
  112. * @default "Remove tag"
  113. */
  114. this.intlRemoveTag = TEXT.removeTag;
  115. //--------------------------------------------------------------------------
  116. //
  117. // Private State/Props
  118. //
  119. //--------------------------------------------------------------------------
  120. this.placement = floatingUi.defaultMenuPlacement;
  121. this.internalValueChangeFlag = false;
  122. this.items = [];
  123. this.groupItems = [];
  124. this.selectedItems = [];
  125. this.visibleItems = [];
  126. this.activeItemIndex = -1;
  127. this.activeChipIndex = -1;
  128. this.activeDescendant = "";
  129. this.text = "";
  130. this.textInput = null;
  131. this.mutationObserver = observers.createObserver("mutation", () => this.updateItems());
  132. this.resizeObserver = observers.createObserver("resize", () => this.setMaxScrollerHeight());
  133. this.guid = guid.guid();
  134. this.inputHeight = 0;
  135. this.ignoreSelectedEventsFlag = false;
  136. this.openTransitionProp = "opacity";
  137. // --------------------------------------------------------------------------
  138. //
  139. // Private Methods
  140. //
  141. // --------------------------------------------------------------------------
  142. this.setFilteredPlacements = () => {
  143. const { el, flipPlacements } = this;
  144. this.filteredFlipPlacements = flipPlacements
  145. ? floatingUi.filterComputedPlacements(flipPlacements, el)
  146. : null;
  147. };
  148. this.getValue = () => {
  149. 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(); });
  150. return (items === null || items === void 0 ? void 0 : items.length) ? (items.length > 1 ? items : items[0]) : "";
  151. };
  152. this.onLabelClick = () => {
  153. this.setFocus();
  154. };
  155. this.keydownHandler = (event) => {
  156. const { key } = event;
  157. switch (key) {
  158. case "Tab":
  159. this.activeChipIndex = -1;
  160. this.activeItemIndex = -1;
  161. if (this.allowCustomValues && this.text) {
  162. this.addCustomChip(this.text, true);
  163. event.preventDefault();
  164. }
  165. else if (this.open) {
  166. this.open = false;
  167. event.preventDefault();
  168. }
  169. break;
  170. case "ArrowLeft":
  171. this.previousChip();
  172. event.preventDefault();
  173. break;
  174. case "ArrowRight":
  175. this.nextChip();
  176. event.preventDefault();
  177. break;
  178. case "ArrowUp":
  179. event.preventDefault();
  180. this.shiftActiveItemIndex(-1);
  181. if (!this.comboboxInViewport()) {
  182. this.el.scrollIntoView();
  183. }
  184. break;
  185. case "ArrowDown":
  186. event.preventDefault();
  187. if (!this.open) {
  188. this.open = true;
  189. }
  190. this.shiftActiveItemIndex(1);
  191. if (!this.comboboxInViewport()) {
  192. this.el.scrollIntoView();
  193. }
  194. break;
  195. case " ":
  196. if (!this.textInput.value) {
  197. event.preventDefault();
  198. this.open = true;
  199. this.shiftActiveItemIndex(1);
  200. }
  201. break;
  202. case "Home":
  203. if (!this.open) {
  204. return;
  205. }
  206. event.preventDefault();
  207. this.updateActiveItemIndex(0);
  208. this.scrollToActiveItem();
  209. if (!this.comboboxInViewport()) {
  210. this.el.scrollIntoView();
  211. }
  212. break;
  213. case "End":
  214. if (!this.open) {
  215. return;
  216. }
  217. event.preventDefault();
  218. this.updateActiveItemIndex(this.visibleItems.length - 1);
  219. this.scrollToActiveItem();
  220. if (!this.comboboxInViewport()) {
  221. this.el.scrollIntoView();
  222. }
  223. break;
  224. case "Escape":
  225. this.open = false;
  226. event.preventDefault();
  227. break;
  228. case "Enter":
  229. if (this.activeItemIndex > -1) {
  230. this.toggleSelection(this.visibleItems[this.activeItemIndex]);
  231. event.preventDefault();
  232. }
  233. else if (this.activeChipIndex > -1) {
  234. this.removeActiveChip();
  235. event.preventDefault();
  236. }
  237. else if (this.allowCustomValues && this.text) {
  238. this.addCustomChip(this.text, true);
  239. event.preventDefault();
  240. }
  241. else if (!event.defaultPrevented) {
  242. if (form.submitForm(this)) {
  243. event.preventDefault();
  244. }
  245. }
  246. break;
  247. case "Delete":
  248. case "Backspace":
  249. if (this.activeChipIndex > -1) {
  250. event.preventDefault();
  251. this.removeActiveChip();
  252. }
  253. else if (!this.text && this.isMulti()) {
  254. event.preventDefault();
  255. this.removeLastChip();
  256. }
  257. break;
  258. }
  259. };
  260. this.toggleCloseEnd = () => {
  261. this.open = false;
  262. this.el.removeEventListener("calciteComboboxClose", this.toggleCloseEnd);
  263. };
  264. this.toggleOpenEnd = () => {
  265. this.open = false;
  266. this.el.removeEventListener("calciteComboboxOpen", this.toggleOpenEnd);
  267. };
  268. this.setMaxScrollerHeight = async () => {
  269. const { listContainerEl, open, referenceEl } = this;
  270. if (!listContainerEl || !open) {
  271. return;
  272. }
  273. await this.reposition(true);
  274. const maxScrollerHeight = this.getMaxScrollerHeight();
  275. listContainerEl.style.maxHeight = maxScrollerHeight > 0 ? `${maxScrollerHeight}px` : "";
  276. listContainerEl.style.minWidth = `${referenceEl.clientWidth}px`;
  277. await this.reposition(true);
  278. };
  279. this.calciteChipDismissHandler = (event, comboboxItem) => {
  280. this.open = false;
  281. const selection = this.items.find((item) => item === comboboxItem);
  282. if (selection) {
  283. this.toggleSelection(selection, false);
  284. }
  285. this.calciteComboboxChipDismiss.emit(event.detail);
  286. };
  287. this.clickHandler = (event) => {
  288. if (event.composedPath().some((node) => node.tagName === "CALCITE-CHIP")) {
  289. return;
  290. }
  291. this.open = !this.open;
  292. this.updateActiveItemIndex(0);
  293. this.setFocus();
  294. };
  295. this.setInactiveIfNotContained = (event) => {
  296. const composedPath = event.composedPath();
  297. if (!this.open || composedPath.includes(this.el) || composedPath.includes(this.referenceEl)) {
  298. return;
  299. }
  300. if (this.allowCustomValues && this.text.trim().length) {
  301. this.addCustomChip(this.text);
  302. }
  303. if (this.selectionMode === "single") {
  304. if (this.textInput) {
  305. this.textInput.value = "";
  306. }
  307. this.text = "";
  308. this.filterItems("");
  309. this.updateActiveItemIndex(-1);
  310. }
  311. this.open = false;
  312. };
  313. this.setFloatingEl = (el) => {
  314. this.floatingEl = el;
  315. floatingUi.connectFloatingUI(this, this.referenceEl, this.floatingEl);
  316. };
  317. this.setContainerEl = (el) => {
  318. this.resizeObserver.observe(el);
  319. this.listContainerEl = el;
  320. this.transitionEl = el;
  321. openCloseComponent.connectOpenCloseComponent(this);
  322. };
  323. this.setReferenceEl = (el) => {
  324. this.referenceEl = el;
  325. floatingUi.connectFloatingUI(this, this.referenceEl, this.floatingEl);
  326. };
  327. this.inputHandler = (event) => {
  328. const value = event.target.value;
  329. this.text = value;
  330. this.filterItems(value);
  331. if (value) {
  332. this.activeChipIndex = -1;
  333. }
  334. };
  335. this.filterItems = (() => {
  336. const find = (item, filteredData) => item &&
  337. filteredData.some(({ label, value }) => {
  338. if (isGroup(item)) {
  339. return value === item.label;
  340. }
  341. return (value === item.textLabel ||
  342. value === item.value ||
  343. label === item.textLabel ||
  344. label === item.value);
  345. });
  346. return debounce.debounce((text) => {
  347. const filteredData = filter.filter(this.data, text);
  348. const items = this.getCombinedItems();
  349. items.forEach((item) => {
  350. const hidden = !find(item, filteredData);
  351. item.hidden = hidden;
  352. const [parent, grandparent] = item.ancestors;
  353. if (find(parent, filteredData) || find(grandparent, filteredData)) {
  354. item.hidden = false;
  355. }
  356. if (!hidden) {
  357. item.ancestors.forEach((ancestor) => (ancestor.hidden = false));
  358. }
  359. });
  360. this.visibleItems = this.getVisibleItems();
  361. this.calciteComboboxFilterChange.emit({ visibleItems: [...this.visibleItems], text: text });
  362. }, 100);
  363. })();
  364. this.internalCalciteLookupChangeEvent = () => {
  365. this.calciteLookupChange.emit(this.selectedItems);
  366. };
  367. this.emitCalciteLookupChange = debounce.debounce(this.internalCalciteLookupChangeEvent, 0);
  368. this.internalComboboxChangeEvent = () => {
  369. const { selectedItems } = this;
  370. this.calciteComboboxChange.emit({ selectedItems });
  371. };
  372. this.emitComboboxChange = debounce.debounce(this.internalComboboxChangeEvent, 0);
  373. this.updateItems = () => {
  374. this.items = this.getItems();
  375. this.groupItems = this.getGroupItems();
  376. this.data = this.getData();
  377. this.selectedItems = this.getSelectedItems();
  378. this.visibleItems = this.getVisibleItems();
  379. this.needsIcon = this.getNeedsIcon();
  380. if (!this.allowCustomValues) {
  381. this.setMaxScrollerHeight();
  382. }
  383. };
  384. this.scrollToActiveItem = () => {
  385. const activeItem = this.visibleItems[this.activeItemIndex];
  386. const height = this.calculateSingleItemHeight(activeItem);
  387. const { offsetHeight, scrollTop } = this.listContainerEl;
  388. if (offsetHeight + scrollTop < activeItem.offsetTop + height) {
  389. this.listContainerEl.scrollTop = activeItem.offsetTop - offsetHeight + height;
  390. }
  391. else if (activeItem.offsetTop < scrollTop) {
  392. this.listContainerEl.scrollTop = activeItem.offsetTop;
  393. }
  394. };
  395. this.comboboxFocusHandler = () => {
  396. var _a;
  397. (_a = this.textInput) === null || _a === void 0 ? void 0 : _a.focus();
  398. };
  399. this.comboboxBlurHandler = (event) => {
  400. this.setInactiveIfNotContained(event);
  401. };
  402. }
  403. activeHandler(value) {
  404. if (this.disabled) {
  405. this.active = false;
  406. this.open = false;
  407. return;
  408. }
  409. this.open = value;
  410. }
  411. openHandler(value) {
  412. if (!value) {
  413. floatingUi.updateAfterClose(this.floatingEl);
  414. }
  415. if (this.disabled) {
  416. this.active = false;
  417. this.open = false;
  418. return;
  419. }
  420. this.active = value;
  421. this.setMaxScrollerHeight();
  422. }
  423. handleDisabledChange(value) {
  424. if (!value) {
  425. this.active = false;
  426. this.open = false;
  427. }
  428. }
  429. maxItemsHandler() {
  430. this.setMaxScrollerHeight();
  431. }
  432. overlayPositioningHandler() {
  433. this.reposition(true);
  434. }
  435. valueHandler(value) {
  436. if (!this.internalValueChangeFlag) {
  437. const items = this.getItems();
  438. if (Array.isArray(value)) {
  439. items.forEach((item) => (item.selected = value.includes(item.value)));
  440. }
  441. else if (value) {
  442. items.forEach((item) => (item.selected = value === item.value));
  443. }
  444. else {
  445. items.forEach((item) => (item.selected = false));
  446. }
  447. this.updateItems();
  448. }
  449. }
  450. flipPlacementsHandler() {
  451. this.setFilteredPlacements();
  452. this.reposition(true);
  453. }
  454. //--------------------------------------------------------------------------
  455. //
  456. // Event Listeners
  457. //
  458. //--------------------------------------------------------------------------
  459. documentClickHandler(event) {
  460. if (!dom.isPrimaryPointerButton(event)) {
  461. return;
  462. }
  463. this.setInactiveIfNotContained(event);
  464. }
  465. calciteComboboxItemChangeHandler(event) {
  466. if (this.ignoreSelectedEventsFlag) {
  467. return;
  468. }
  469. const target = event.target;
  470. const newIndex = this.visibleItems.indexOf(target);
  471. this.updateActiveItemIndex(newIndex);
  472. this.toggleSelection(target, target.selected);
  473. }
  474. //--------------------------------------------------------------------------
  475. //
  476. // Public Methods
  477. //
  478. //--------------------------------------------------------------------------
  479. /**
  480. * Updates the position of the component.
  481. *
  482. * @param delayed
  483. */
  484. async reposition(delayed = false) {
  485. const { floatingEl, referenceEl, placement, overlayPositioning, filteredFlipPlacements } = this;
  486. return floatingUi.reposition(this, {
  487. floatingEl,
  488. referenceEl,
  489. overlayPositioning,
  490. placement,
  491. flipPlacements: filteredFlipPlacements,
  492. type: "menu"
  493. }, delayed);
  494. }
  495. /** Sets focus on the component. */
  496. async setFocus() {
  497. var _a;
  498. (_a = this.textInput) === null || _a === void 0 ? void 0 : _a.focus();
  499. this.activeChipIndex = -1;
  500. this.activeItemIndex = -1;
  501. }
  502. // --------------------------------------------------------------------------
  503. //
  504. // Lifecycle
  505. //
  506. // --------------------------------------------------------------------------
  507. connectedCallback() {
  508. var _a;
  509. this.internalValueChangeFlag = true;
  510. this.value = this.getValue();
  511. this.internalValueChangeFlag = false;
  512. (_a = this.mutationObserver) === null || _a === void 0 ? void 0 : _a.observe(this.el, { childList: true, subtree: true });
  513. label.connectLabel(this);
  514. form.connectForm(this);
  515. openCloseComponent.connectOpenCloseComponent(this);
  516. this.setFilteredPlacements();
  517. this.reposition(true);
  518. if (this.active) {
  519. this.activeHandler(this.active);
  520. }
  521. if (this.open) {
  522. this.openHandler(this.open);
  523. }
  524. }
  525. componentWillLoad() {
  526. this.updateItems();
  527. }
  528. componentDidLoad() {
  529. form.afterConnectDefaultValueSet(this, this.getValue());
  530. this.reposition(true);
  531. }
  532. componentDidRender() {
  533. if (this.el.offsetHeight !== this.inputHeight) {
  534. this.reposition(true);
  535. this.inputHeight = this.el.offsetHeight;
  536. }
  537. interactive.updateHostInteraction(this);
  538. }
  539. disconnectedCallback() {
  540. var _a, _b;
  541. (_a = this.mutationObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
  542. (_b = this.resizeObserver) === null || _b === void 0 ? void 0 : _b.disconnect();
  543. label.disconnectLabel(this);
  544. form.disconnectForm(this);
  545. floatingUi.disconnectFloatingUI(this, this.referenceEl, this.floatingEl);
  546. openCloseComponent.disconnectOpenCloseComponent(this);
  547. }
  548. selectedItemsHandler() {
  549. this.internalValueChangeFlag = true;
  550. this.value = this.getValue();
  551. this.internalValueChangeFlag = false;
  552. }
  553. /** when search text is cleared, reset active to */
  554. textHandler() {
  555. this.updateActiveItemIndex(-1);
  556. }
  557. comboboxInViewport() {
  558. const bounding = this.el.getBoundingClientRect();
  559. return (bounding.top >= 0 &&
  560. bounding.left >= 0 &&
  561. bounding.right <= (window.innerWidth || document.documentElement.clientWidth) &&
  562. bounding.bottom <= (window.innerHeight || document.documentElement.clientHeight));
  563. }
  564. onBeforeOpen() {
  565. this.calciteComboboxBeforeOpen.emit();
  566. }
  567. onOpen() {
  568. this.calciteComboboxOpen.emit();
  569. }
  570. onBeforeClose() {
  571. this.calciteComboboxBeforeClose.emit();
  572. }
  573. onClose() {
  574. this.calciteComboboxClose.emit();
  575. }
  576. getMaxScrollerHeight() {
  577. const items = this.getCombinedItems().filter((item) => !item.hidden);
  578. const { maxItems } = this;
  579. let itemsToProcess = 0;
  580. let maxScrollerHeight = 0;
  581. if (items.length > maxItems) {
  582. items.forEach((item) => {
  583. if (itemsToProcess < maxItems && maxItems > 0) {
  584. const height = this.calculateSingleItemHeight(item);
  585. if (height > 0) {
  586. maxScrollerHeight += height;
  587. itemsToProcess++;
  588. }
  589. }
  590. });
  591. }
  592. return maxScrollerHeight;
  593. }
  594. calculateSingleItemHeight(item) {
  595. let height = item.offsetHeight;
  596. // if item has children items, don't count their height twice
  597. const children = Array.from(item.querySelectorAll(ComboboxChildSelector));
  598. children
  599. .map((child) => child === null || child === void 0 ? void 0 : child.offsetHeight)
  600. .forEach((offsetHeight) => {
  601. height -= offsetHeight;
  602. });
  603. return height;
  604. }
  605. getCombinedItems() {
  606. return [...this.groupItems, ...this.items];
  607. }
  608. toggleSelection(item, value = !item.selected) {
  609. if (!item) {
  610. return;
  611. }
  612. if (this.isMulti()) {
  613. item.selected = value;
  614. this.updateAncestors(item);
  615. this.selectedItems = this.getSelectedItems();
  616. this.emitCalciteLookupChange();
  617. this.emitComboboxChange();
  618. this.resetText();
  619. this.filterItems("");
  620. }
  621. else {
  622. this.ignoreSelectedEventsFlag = true;
  623. this.items.forEach((el) => (el.selected = el === item ? value : false));
  624. this.ignoreSelectedEventsFlag = false;
  625. this.selectedItems = this.getSelectedItems();
  626. this.emitComboboxChange();
  627. if (this.textInput) {
  628. this.textInput.value = item.textLabel;
  629. }
  630. this.open = false;
  631. this.updateActiveItemIndex(-1);
  632. this.resetText();
  633. this.filterItems("");
  634. }
  635. }
  636. updateAncestors(item) {
  637. if (this.selectionMode !== "ancestors") {
  638. return;
  639. }
  640. const ancestors = getItemAncestors(item);
  641. const children = getItemChildren(item);
  642. if (item.selected) {
  643. ancestors.forEach((el) => {
  644. el.selected = true;
  645. });
  646. }
  647. else {
  648. children.forEach((el) => (el.selected = false));
  649. [...ancestors].forEach((el) => {
  650. if (!hasActiveChildren(el)) {
  651. el.selected = false;
  652. }
  653. });
  654. }
  655. }
  656. getVisibleItems() {
  657. return this.items.filter((item) => !item.hidden);
  658. }
  659. getSelectedItems() {
  660. if (!this.isMulti()) {
  661. const match = this.items.find(({ selected }) => selected);
  662. return match ? [match] : [];
  663. }
  664. return (this.items
  665. .filter((item) => item.selected && (this.selectionMode !== "ancestors" || !hasActiveChildren(item)))
  666. /** Preserve order of entered tags */
  667. .sort((a, b) => {
  668. const aIdx = this.selectedItems.indexOf(a);
  669. const bIdx = this.selectedItems.indexOf(b);
  670. if (aIdx > -1 && bIdx > -1) {
  671. return aIdx - bIdx;
  672. }
  673. return bIdx - aIdx;
  674. }));
  675. }
  676. getData() {
  677. return this.items.map((item) => ({
  678. constant: item.constant,
  679. filterDisabled: item.filterDisabled,
  680. value: item.value,
  681. label: item.textLabel
  682. }));
  683. }
  684. getNeedsIcon() {
  685. return this.selectionMode === "single" && this.items.some((item) => item.icon);
  686. }
  687. resetText() {
  688. if (this.textInput) {
  689. this.textInput.value = "";
  690. }
  691. this.text = "";
  692. }
  693. getItems() {
  694. const items = Array.from(this.el.querySelectorAll(ComboboxItem$1));
  695. return items.filter((item) => !item.disabled);
  696. }
  697. getGroupItems() {
  698. return Array.from(this.el.querySelectorAll(ComboboxItemGroup$1));
  699. }
  700. addCustomChip(value, focus) {
  701. const existingItem = this.items.find((el) => el.textLabel === value);
  702. if (existingItem) {
  703. this.toggleSelection(existingItem, true);
  704. }
  705. else {
  706. if (!this.isMulti()) {
  707. this.toggleSelection(this.selectedItems[this.selectedItems.length - 1], false);
  708. }
  709. const item = document.createElement(ComboboxItem$1);
  710. item.value = value;
  711. item.textLabel = value;
  712. item.selected = true;
  713. this.el.appendChild(item);
  714. this.resetText();
  715. if (focus) {
  716. this.setFocus();
  717. }
  718. this.updateItems();
  719. this.filterItems("");
  720. this.emitCalciteLookupChange();
  721. this.emitComboboxChange();
  722. }
  723. }
  724. removeActiveChip() {
  725. this.toggleSelection(this.selectedItems[this.activeChipIndex], false);
  726. this.setFocus();
  727. }
  728. removeLastChip() {
  729. this.toggleSelection(this.selectedItems[this.selectedItems.length - 1], false);
  730. this.setFocus();
  731. }
  732. previousChip() {
  733. if (this.text) {
  734. return;
  735. }
  736. const length = this.selectedItems.length - 1;
  737. const active = this.activeChipIndex;
  738. this.activeChipIndex = active === -1 ? length : Math.max(active - 1, 0);
  739. this.updateActiveItemIndex(-1);
  740. this.focusChip();
  741. }
  742. nextChip() {
  743. if (this.text || this.activeChipIndex === -1) {
  744. return;
  745. }
  746. const last = this.selectedItems.length - 1;
  747. const newIndex = this.activeChipIndex + 1;
  748. if (newIndex > last) {
  749. this.activeChipIndex = -1;
  750. this.setFocus();
  751. }
  752. else {
  753. this.activeChipIndex = newIndex;
  754. this.focusChip();
  755. }
  756. this.updateActiveItemIndex(-1);
  757. }
  758. focusChip() {
  759. var _a;
  760. const guid = (_a = this.selectedItems[this.activeChipIndex]) === null || _a === void 0 ? void 0 : _a.guid;
  761. const chip = guid
  762. ? this.referenceEl.querySelector(`#${chipUidPrefix}${guid}`)
  763. : null;
  764. chip === null || chip === void 0 ? void 0 : chip.setFocus();
  765. }
  766. shiftActiveItemIndex(delta) {
  767. const { length } = this.visibleItems;
  768. const newIndex = (this.activeItemIndex + length + delta) % length;
  769. this.updateActiveItemIndex(newIndex);
  770. this.scrollToActiveItem();
  771. }
  772. updateActiveItemIndex(index) {
  773. var _a;
  774. this.activeItemIndex = index;
  775. let activeDescendant = null;
  776. this.visibleItems.forEach((el, i) => {
  777. if (i === index) {
  778. el.active = true;
  779. activeDescendant = `${itemUidPrefix}${el.guid}`;
  780. }
  781. else {
  782. el.active = false;
  783. }
  784. });
  785. this.activeDescendant = activeDescendant;
  786. if (this.activeItemIndex > -1) {
  787. this.activeChipIndex = -1;
  788. (_a = this.textInput) === null || _a === void 0 ? void 0 : _a.focus();
  789. }
  790. }
  791. isMulti() {
  792. return this.selectionMode !== "single";
  793. }
  794. //--------------------------------------------------------------------------
  795. //
  796. // Render Methods
  797. //
  798. //--------------------------------------------------------------------------
  799. renderChips() {
  800. const { activeChipIndex, scale, selectionMode, intlRemoveTag } = this;
  801. return this.selectedItems.map((item, i) => {
  802. const chipClasses = {
  803. chip: true,
  804. "chip--active": activeChipIndex === i
  805. };
  806. const ancestors = [...getItemAncestors(item)].reverse();
  807. const pathLabel = [...ancestors, item].map((el) => el.textLabel);
  808. const label = selectionMode !== "ancestors" ? item.textLabel : pathLabel.join(" / ");
  809. return (index.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));
  810. });
  811. }
  812. renderInput() {
  813. const { guid, active, disabled, placeholder, selectionMode, selectedItems, open } = this;
  814. const single = selectionMode === "single";
  815. const selectedItem = selectedItems[0];
  816. const showLabel = !(open || active) && single && !!selectedItem;
  817. return (index.h("span", { class: {
  818. "input-wrap": true,
  819. "input-wrap--single": single
  820. } }, showLabel && (index.h("span", { class: {
  821. label: true,
  822. "label--icon": !!(selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.icon)
  823. }, key: "label" }, selectedItem.textLabel)), index.h("input", { "aria-activedescendant": this.activeDescendant, "aria-autocomplete": "list", "aria-controls": `${listboxUidPrefix}${guid}`, "aria-label": label.getLabelText(this), class: {
  824. input: true,
  825. "input--single": true,
  826. "input--transparent": this.activeChipIndex > -1,
  827. "input--hidden": showLabel,
  828. "input--icon": !!this.placeholderIcon
  829. }, 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" })));
  830. }
  831. renderListBoxOptions() {
  832. return this.visibleItems.map((item) => (index.h("li", { "aria-selected": dom.toAriaBoolean(item.selected), id: item.guid ? `${itemUidPrefix}${item.guid}` : null, role: "option", tabindex: "-1" }, item.textLabel)));
  833. }
  834. renderFloatingUIContainer() {
  835. const { active, setFloatingEl, setContainerEl, open } = this;
  836. const classes = {
  837. "list-container": true,
  838. [floatingUi.FloatingCSS.animation]: true,
  839. [floatingUi.FloatingCSS.animationActive]: open || active
  840. };
  841. return (index.h("div", { "aria-hidden": "true", class: {
  842. "floating-ui-container": true,
  843. "floating-ui-container--active": open || active
  844. }, ref: setFloatingEl }, index.h("div", { class: classes, ref: setContainerEl }, index.h("ul", { class: { list: true, "list--hide": !(open || active) } }, index.h("slot", null)))));
  845. }
  846. renderIconStart() {
  847. const { selectedItems, placeholderIcon, selectionMode } = this;
  848. const selectedItem = selectedItems[0];
  849. const selectedIcon = selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.icon;
  850. const singleSelectionMode = selectionMode === "single";
  851. const iconAtStart = !this.open && selectedItem
  852. ? !!selectedIcon && singleSelectionMode
  853. : !!this.placeholderIcon && (!selectedItem || singleSelectionMode);
  854. return (iconAtStart && (index.h("span", { class: "icon-start" }, index.h("calcite-icon", { class: "selected-icon", icon: !this.open && selectedItem ? selectedIcon : placeholderIcon, scale: "s" }))));
  855. }
  856. renderIconEnd() {
  857. const { active, open } = this;
  858. return (index.h("span", { class: "icon-end" }, index.h("calcite-icon", { icon: active || open ? "chevron-up" : "chevron-down", scale: "s" })));
  859. }
  860. render() {
  861. const { active, guid, label, open } = this;
  862. const single = this.selectionMode === "single";
  863. return (index.h(index.Host, null, index.h("div", { "aria-autocomplete": "list", "aria-controls": `${listboxUidPrefix}${guid}`, "aria-expanded": dom.toAriaBoolean(open || active), "aria-haspopup": "listbox", "aria-labelledby": `${labelUidPrefix}${guid}`, "aria-live": "polite", "aria-owns": `${listboxUidPrefix}${guid}`, class: {
  864. wrapper: true,
  865. "wrapper--single": single || !this.selectedItems.length,
  866. "wrapper--active": open || active
  867. }, onClick: this.clickHandler, onKeyDown: this.keydownHandler, ref: this.setReferenceEl, role: "combobox" }, index.h("div", { class: "grid-input" }, this.renderIconStart(), !single && this.renderChips(), index.h("label", { class: "screen-readers-only", htmlFor: `${inputUidPrefix}${guid}`, id: `${labelUidPrefix}${guid}` }, label), this.renderInput()), this.renderIconEnd()), index.h("ul", { "aria-labelledby": `${labelUidPrefix}${guid}`, "aria-multiselectable": "true", class: "screen-readers-only", id: `${listboxUidPrefix}${guid}`, role: "listbox", tabIndex: -1 }, this.renderListBoxOptions()), this.renderFloatingUIContainer(), index.h(form.HiddenFormInputSlot, { component: this })));
  868. }
  869. get el() { return index.getElement(this); }
  870. static get watchers() { return {
  871. "active": ["activeHandler"],
  872. "open": ["openHandler"],
  873. "disabled": ["handleDisabledChange"],
  874. "maxItems": ["maxItemsHandler"],
  875. "overlayPositioning": ["overlayPositioningHandler"],
  876. "value": ["valueHandler"],
  877. "flipPlacements": ["flipPlacementsHandler"],
  878. "selectedItems": ["selectedItemsHandler"],
  879. "text": ["textHandler"]
  880. }; }
  881. };
  882. Combobox.style = comboboxCss;
  883. const CSS$1 = {
  884. icon: "icon",
  885. iconActive: "icon--active",
  886. custom: "icon--custom",
  887. dot: "icon--dot",
  888. single: "label--single",
  889. label: "label",
  890. active: "label--active",
  891. selected: "label--selected",
  892. title: "title",
  893. textContainer: "text-container"
  894. };
  895. const comboboxItemCss = "@charset \"UTF-8\";@keyframes in{0%{opacity:0}100%{opacity:1}}@keyframes in-down{0%{opacity:0;transform:translate3D(0, -5px, 0)}100%{opacity:1;transform:translate3D(0, 0, 0)}}@keyframes in-up{0%{opacity:0;transform:translate3D(0, 5px, 0)}100%{opacity:1;transform:translate3D(0, 0, 0)}}@keyframes in-scale{0%{opacity:0;transform:scale3D(0.95, 0.95, 1)}100%{opacity:1;transform:scale3D(1, 1, 1)}}:root{--calcite-animation-timing:calc(150ms * var(--calcite-internal-duration-factor));--calcite-internal-duration-factor:var(--calcite-duration-factor, 1);--calcite-internal-animation-timing-fast:calc(100ms * var(--calcite-internal-duration-factor));--calcite-internal-animation-timing-medium:calc(200ms * var(--calcite-internal-duration-factor));--calcite-internal-animation-timing-slow:calc(300ms * var(--calcite-internal-duration-factor))}.calcite-animate{opacity:0;animation-fill-mode:both;animation-duration:var(--calcite-animation-timing)}.calcite-animate__in{animation-name:in}.calcite-animate__in-down{animation-name:in-down}.calcite-animate__in-up{animation-name:in-up}.calcite-animate__in-scale{animation-name:in-scale}@media (prefers-reduced-motion: reduce){:root{--calcite-internal-duration-factor:0.01}}:root{--calcite-floating-ui-transition:var(--calcite-animation-timing)}:host([hidden]){display:none}:host([disabled]){pointer-events:none;cursor:default;-webkit-user-select:none;user-select:none;opacity:var(--calcite-ui-opacity-disabled)}.scale--s{font-size:var(--calcite-font-size--2);line-height:1rem;--calcite-combobox-item-spacing-unit-l:0.5rem;--calcite-combobox-item-spacing-unit-s:0.25rem;--calcite-combobox-item-spacing-indent:0.5rem}.scale--m{font-size:var(--calcite-font-size--1);line-height:1rem;--calcite-combobox-item-spacing-unit-l:0.75rem;--calcite-combobox-item-spacing-unit-s:0.5rem;--calcite-combobox-item-spacing-indent:0.75rem}.scale--l{font-size:var(--calcite-font-size-0);line-height:1.25rem;--calcite-combobox-item-spacing-unit-l:1rem;--calcite-combobox-item-spacing-unit-s:0.75rem;--calcite-combobox-item-spacing-indent:1rem}.container{--calcite-combobox-item-indent-value:calc(\n var(--calcite-combobox-item-spacing-indent) * var(--calcite-combobox-item-spacing-indent-multiplier)\n )}:host(:focus){--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow)}:host([disabled]) ::slotted([calcite-hydrated][disabled]),:host([disabled]) [calcite-hydrated][disabled]{opacity:1}:host,ul{margin:0px;display:flex;flex-direction:column;padding:0px}:host(:focus),ul:focus{outline:2px solid transparent;outline-offset:2px}.label{position:relative;box-sizing:border-box;display:flex;inline-size:100%;min-inline-size:100%;cursor:pointer;align-items:center;color:var(--calcite-ui-text-3);text-decoration-line:none;transition-duration:150ms;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);outline-color:transparent;padding-block:var(--calcite-combobox-item-spacing-unit-s);padding-inline:var(--calcite-combobox-item-spacing-unit-l)}:host([disabled]) .label{cursor:default}.label--selected{font-weight:var(--calcite-font-weight-medium);color:var(--calcite-ui-text-1)}.label--active{outline:2px solid var(--calcite-ui-brand);outline-offset:-2px}.label:hover,.label:active{background-color:var(--calcite-ui-foreground-2);color:var(--calcite-ui-text-1);text-decoration-line:none;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow)}.title{padding-block:0;padding-inline:var(--calcite-combobox-item-spacing-unit-l)}.icon{display:inline-flex;opacity:0;transition-duration:150ms;transition-timing-function:cubic-bezier(0.4, 0, 0.2, 1);color:var(--calcite-ui-border-1)}.icon--indent{padding-inline-start:var(--calcite-combobox-item-indent-value)}.icon--custom{margin-block-start:-1px;color:var(--calcite-ui-text-3)}.icon--active{color:var(--calcite-ui-text-1)}.icon--dot{display:flex;justify-content:flex-end;min-inline-size:var(--calcite-combobox-item-spacing-unit-l)}.icon--dot:before{text-align:start;content:\"•\"}.label--active .icon{opacity:1}.label--selected .icon{opacity:1;color:var(--calcite-ui-brand)}:host(:hover[disabled]) .icon{opacity:1}";
  896. const ComboboxItem = class {
  897. constructor(hostRef) {
  898. index.registerInstance(this, hostRef);
  899. this.calciteComboboxItemChange = index.createEvent(this, "calciteComboboxItemChange", 6);
  900. // --------------------------------------------------------------------------
  901. //
  902. // Properties
  903. //
  904. // --------------------------------------------------------------------------
  905. /** When `true`, interaction is prevented and the component is displayed with lower opacity. */
  906. this.disabled = false;
  907. /**
  908. * When `true`, the component is selected.
  909. */
  910. this.selected = false;
  911. /** When `true`, the component is active. */
  912. this.active = false;
  913. /** The `id` attribute of the component. When omitted, a globally unique identifier is used. */
  914. this.guid = guid.guid();
  915. this.scale = "m";
  916. // --------------------------------------------------------------------------
  917. //
  918. // Private Methods
  919. //
  920. // --------------------------------------------------------------------------
  921. this.itemClickHandler = (event) => {
  922. event.preventDefault();
  923. if (this.disabled) {
  924. return;
  925. }
  926. this.selected = !this.selected;
  927. };
  928. }
  929. selectedWatchHandler() {
  930. this.calciteComboboxItemChange.emit(this.el);
  931. }
  932. // --------------------------------------------------------------------------
  933. //
  934. // Lifecycle
  935. //
  936. // --------------------------------------------------------------------------
  937. connectedCallback() {
  938. this.ancestors = getAncestors(this.el);
  939. this.scale = dom.getElementProp(this.el, "scale", this.scale);
  940. conditionalSlot.connectConditionalSlotComponent(this);
  941. }
  942. disconnectedCallback() {
  943. conditionalSlot.disconnectConditionalSlotComponent(this);
  944. }
  945. componentDidRender() {
  946. interactive.updateHostInteraction(this);
  947. }
  948. // --------------------------------------------------------------------------
  949. //
  950. // Public Methods
  951. //
  952. // --------------------------------------------------------------------------
  953. /**
  954. * Used to toggle the selection state. By default this won't trigger an event.
  955. * The first argument allows the value to be coerced, rather than swapping values.
  956. *
  957. * @param coerce
  958. */
  959. async toggleSelected(coerce) {
  960. if (this.disabled) {
  961. return;
  962. }
  963. this.selected = typeof coerce === "boolean" ? coerce : !this.selected;
  964. }
  965. // --------------------------------------------------------------------------
  966. //
  967. // Render Methods
  968. //
  969. // --------------------------------------------------------------------------
  970. renderIcon(isSingle) {
  971. const { icon, disabled, selected } = this;
  972. const level = `${CSS$1.icon}--indent`;
  973. const defaultIcon = isSingle ? "dot" : "check";
  974. const iconPath = disabled ? "circle-disallowed" : defaultIcon;
  975. const showDot = isSingle && !icon && !disabled;
  976. return showDot ? (index.h("span", { class: {
  977. [CSS$1.icon]: true,
  978. [CSS$1.dot]: true,
  979. [level]: true
  980. } })) : (index.h("calcite-icon", { class: {
  981. [CSS$1.icon]: !icon,
  982. [CSS$1.custom]: !!icon,
  983. [CSS$1.iconActive]: icon && selected,
  984. [level]: true
  985. }, icon: icon || iconPath, scale: "s" }));
  986. }
  987. renderChildren() {
  988. if (dom.getSlotted(this.el)) {
  989. return (index.h("ul", { key: "default-slot-container" }, index.h("slot", null)));
  990. }
  991. return null;
  992. }
  993. render() {
  994. const isSingleSelect = dom.getElementProp(this.el, "selection-mode", "multi") === "single";
  995. const classes = {
  996. [CSS$1.label]: true,
  997. [CSS$1.selected]: this.selected,
  998. [CSS$1.active]: this.active,
  999. [CSS$1.single]: isSingleSelect
  1000. };
  1001. const depth = getDepth(this.el);
  1002. return (index.h(index.Host, { "aria-hidden": "true" }, index.h("div", { class: `container scale--${this.scale}`, style: { "--calcite-combobox-item-spacing-indent-multiplier": `${depth}` } }, index.h("li", { class: classes, id: this.guid, onClick: this.itemClickHandler }, this.renderIcon(isSingleSelect), index.h("span", { class: CSS$1.title }, this.textLabel)), this.renderChildren())));
  1003. }
  1004. get el() { return index.getElement(this); }
  1005. static get watchers() { return {
  1006. "selected": ["selectedWatchHandler"]
  1007. }; }
  1008. };
  1009. ComboboxItem.style = comboboxItemCss;
  1010. const CSS = {
  1011. list: "list",
  1012. label: "label",
  1013. title: "title"
  1014. };
  1015. const comboboxItemGroupCss = "@keyframes in{0%{opacity:0}100%{opacity:1}}@keyframes in-down{0%{opacity:0;transform:translate3D(0, -5px, 0)}100%{opacity:1;transform:translate3D(0, 0, 0)}}@keyframes in-up{0%{opacity:0;transform:translate3D(0, 5px, 0)}100%{opacity:1;transform:translate3D(0, 0, 0)}}@keyframes in-scale{0%{opacity:0;transform:scale3D(0.95, 0.95, 1)}100%{opacity:1;transform:scale3D(1, 1, 1)}}:root{--calcite-animation-timing:calc(150ms * var(--calcite-internal-duration-factor));--calcite-internal-duration-factor:var(--calcite-duration-factor, 1);--calcite-internal-animation-timing-fast:calc(100ms * var(--calcite-internal-duration-factor));--calcite-internal-animation-timing-medium:calc(200ms * var(--calcite-internal-duration-factor));--calcite-internal-animation-timing-slow:calc(300ms * var(--calcite-internal-duration-factor))}.calcite-animate{opacity:0;animation-fill-mode:both;animation-duration:var(--calcite-animation-timing)}.calcite-animate__in{animation-name:in}.calcite-animate__in-down{animation-name:in-down}.calcite-animate__in-up{animation-name:in-up}.calcite-animate__in-scale{animation-name:in-scale}@media (prefers-reduced-motion: reduce){:root{--calcite-internal-duration-factor:0.01}}:root{--calcite-floating-ui-transition:var(--calcite-animation-timing)}:host([hidden]){display:none}.scale--s{font-size:var(--calcite-font-size--2);line-height:1rem;--calcite-combobox-item-spacing-unit-l:0.5rem;--calcite-combobox-item-spacing-unit-s:0.25rem;--calcite-combobox-item-spacing-indent-1:0.5rem;--calcite-combobox-item-spacing-indent-2:1rem}.scale--m{font-size:var(--calcite-font-size--1);line-height:1rem;--calcite-combobox-item-spacing-unit-l:0.75rem;--calcite-combobox-item-spacing-unit-s:0.5rem;--calcite-combobox-item-spacing-indent-1:0.75rem;--calcite-combobox-item-spacing-indent-2:1.5rem}.scale--l{font-size:var(--calcite-font-size-0);line-height:1.25rem;--calcite-combobox-item-spacing-unit-l:1rem;--calcite-combobox-item-spacing-unit-s:0.75rem;--calcite-combobox-item-spacing-indent-1:1rem;--calcite-combobox-item-spacing-indent-2:2rem}:host,.list{margin:0px;display:flex;flex-direction:column;padding:0px}:host(:focus),.list:focus{outline:2px solid transparent;outline-offset:2px}.label{box-sizing:border-box;display:flex;inline-size:100%;min-inline-size:0px;max-inline-size:100%;color:var(--calcite-ui-text-3)}.label--indent-1{padding-inline-start:var(--calcite-combobox-item-spacing-indent-1)}.label--indent-2{padding-inline-start:var(--calcite-combobox-item-spacing-indent-2)}.title{border:0 solid;display:block;flex:1 1 0%;border-block-end-width:1px;font-weight:var(--calcite-font-weight-bold);color:var(--calcite-ui-text-2);word-wrap:break-word;word-break:break-word;border-block-end-color:var(--calcite-ui-border-3);padding-block:var(--calcite-combobox-item-spacing-unit-l);padding-inline:0;margin-inline:var(--calcite-combobox-item-spacing-unit-s)}";
  1016. const ComboboxItemGroup = class {
  1017. constructor(hostRef) {
  1018. index.registerInstance(this, hostRef);
  1019. this.guid = guid.guid();
  1020. this.scale = "m";
  1021. }
  1022. // --------------------------------------------------------------------------
  1023. //
  1024. // Lifecycle
  1025. //
  1026. // --------------------------------------------------------------------------
  1027. connectedCallback() {
  1028. this.ancestors = getAncestors(this.el);
  1029. this.scale = dom.getElementProp(this.el, "scale", this.scale);
  1030. }
  1031. // --------------------------------------------------------------------------
  1032. //
  1033. // Render Methods
  1034. //
  1035. // --------------------------------------------------------------------------
  1036. render() {
  1037. const { el, scale } = this;
  1038. const indent = `${CSS.label}--indent-${getDepth(el)}`;
  1039. return (index.h("ul", { "aria-labelledby": this.guid, class: { [CSS.list]: true, [`scale--${scale}`]: true }, role: "group" }, index.h("li", { class: { [CSS.label]: true, [indent]: true }, id: this.guid, role: "presentation" }, index.h("span", { class: CSS.title }, this.label)), index.h("slot", null)));
  1040. }
  1041. get el() { return index.getElement(this); }
  1042. };
  1043. ComboboxItemGroup.style = comboboxItemGroupCss;
  1044. exports.calcite_combobox = Combobox;
  1045. exports.calcite_combobox_item = ComboboxItem;
  1046. exports.calcite_combobox_item_group = ComboboxItemGroup;