calcite-combobox_3.cjs.entry.js 57 KB

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