resources-c4ee68b9.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  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. import { f as focusElement, g as getSlotted, t as toAriaBoolean } from './dom-da697a3f.js';
  7. import { g as getRoundRobinIndex } from './array-1655bbf7.js';
  8. import { d as debounce } from './debounce-c4df98cc.js';
  9. import { h, H as Host } from './index-8ece2564.js';
  10. const CSS$2 = {
  11. heading: "heading",
  12. container: "container",
  13. indented: "container--indented"
  14. };
  15. const SLOTS$2 = {
  16. parentItem: "parent-item"
  17. };
  18. const HEADING_LEVEL = 3;
  19. function mutationObserverCallback() {
  20. this.setUpItems();
  21. this.setUpFilter();
  22. this.deselectRemovedItems();
  23. }
  24. const SUPPORTED_ARROW_KEYS = ["ArrowUp", "ArrowDown"];
  25. // --------------------------------------------------------------------------
  26. //
  27. // Lifecycle
  28. //
  29. // --------------------------------------------------------------------------
  30. function initialize() {
  31. this.setUpItems();
  32. this.setUpFilter();
  33. this.emitCalciteListChange = debounce(internalCalciteListChangeEvent.bind(this), 0);
  34. }
  35. function initializeObserver() {
  36. var _a;
  37. (_a = this.mutationObserver) === null || _a === void 0 ? void 0 : _a.observe(this.el, { childList: true, subtree: true });
  38. }
  39. function cleanUpObserver() {
  40. var _a;
  41. (_a = this.mutationObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
  42. }
  43. // --------------------------------------------------------------------------
  44. //
  45. // Listeners
  46. //
  47. // --------------------------------------------------------------------------
  48. function calciteListItemChangeHandler(event) {
  49. const { selectedValues } = this;
  50. const { item, value, selected, shiftPressed } = event.detail;
  51. if (selected) {
  52. if (this.multiple && shiftPressed) {
  53. this.selectSiblings(item);
  54. }
  55. if (!this.multiple) {
  56. this.deselectSiblingItems(item);
  57. }
  58. selectedValues.set(value, item);
  59. }
  60. else {
  61. selectedValues.delete(value);
  62. if (this.multiple && shiftPressed) {
  63. this.selectSiblings(item, true);
  64. }
  65. }
  66. if (!this.multiple) {
  67. toggleSingleSelectItemTabbing(item, selected);
  68. if (selected) {
  69. focusElement(item);
  70. }
  71. }
  72. this.lastSelectedItem = item;
  73. this.emitCalciteListChange();
  74. }
  75. function calciteListItemValueChangeHandler(event) {
  76. event.stopPropagation();
  77. const oldValue = event.detail.oldValue;
  78. const selectedValues = this.selectedValues;
  79. if (selectedValues.has(oldValue)) {
  80. const item = selectedValues.get(oldValue);
  81. selectedValues.delete(oldValue);
  82. selectedValues.set(event.detail.newValue, item);
  83. }
  84. }
  85. // --------------------------------------------------------------------------
  86. //
  87. // Private Methods
  88. //
  89. // --------------------------------------------------------------------------
  90. function isValidNavigationKey(key) {
  91. return !!SUPPORTED_ARROW_KEYS.find((k) => k === key);
  92. }
  93. function calciteListFocusOutHandler(event) {
  94. const { el, items, multiple, selectedValues } = this;
  95. if (multiple) {
  96. return;
  97. }
  98. const focusedInside = el.contains(event.relatedTarget);
  99. if (focusedInside) {
  100. return;
  101. }
  102. filterOutDisabled(items).forEach((item) => {
  103. toggleSingleSelectItemTabbing(item, selectedValues.size === 0 ? item.contains(event.target) || event.target === item : item.selected);
  104. });
  105. }
  106. function keyDownHandler(event) {
  107. const { key, target } = event;
  108. if (!isValidNavigationKey(key)) {
  109. return;
  110. }
  111. const { items, multiple, selectionFollowsFocus } = this;
  112. const { length: totalItems } = items;
  113. const currentIndex = items.indexOf(target);
  114. if (!totalItems || currentIndex === -1) {
  115. return;
  116. }
  117. event.preventDefault();
  118. const index = moveItemIndex(this, target, key === "ArrowUp" ? "up" : "down");
  119. const item = items[index];
  120. items.forEach((i) => toggleSingleSelectItemTabbing(i, i === item));
  121. if (!multiple && selectionFollowsFocus) {
  122. item.selected = true;
  123. }
  124. focusElement(item);
  125. }
  126. function moveItemIndex(list, item, direction) {
  127. const { items } = list;
  128. const { length: totalItems } = items;
  129. const currentIndex = items.indexOf(item);
  130. const directionFactor = direction === "up" ? -1 : 1;
  131. let moveOffset = 1;
  132. let index = getRoundRobinIndex(currentIndex + directionFactor * moveOffset++, totalItems);
  133. const firstMovedIndex = index;
  134. while (items[index].disabled) {
  135. index = getRoundRobinIndex(currentIndex + directionFactor * moveOffset++, totalItems);
  136. if (index === firstMovedIndex) {
  137. break;
  138. }
  139. }
  140. return index;
  141. }
  142. function filterOutDisabled(items) {
  143. return items.filter((item) => !item.disabled);
  144. }
  145. function internalCalciteListChangeEvent() {
  146. this.calciteListChange.emit(this.selectedValues);
  147. }
  148. function removeItem(event) {
  149. if (event.defaultPrevented) {
  150. return;
  151. }
  152. const item = event.target;
  153. const selectedValues = this.selectedValues;
  154. if (item.parentElement.tagName === "CALCITE-PICK-LIST-GROUP" && item.slot === SLOTS$2.parentItem) {
  155. item.parentElement.remove();
  156. Array.from(item.parentElement.children).forEach((item) => selectedValues.delete(item.value));
  157. }
  158. else {
  159. item.remove();
  160. selectedValues.delete(item.value);
  161. }
  162. this.emitCalciteListChange();
  163. }
  164. function toggleSingleSelectItemTabbing(item, selectable) {
  165. if (item.disabled) {
  166. return;
  167. }
  168. // using attribute intentionally
  169. if (selectable) {
  170. item.removeAttribute("tabindex");
  171. }
  172. else {
  173. item.setAttribute("tabindex", "-1");
  174. }
  175. }
  176. async function setFocus(focusId) {
  177. var _a;
  178. if (this.filterEnabled && focusId === "filter") {
  179. await focusElement(this.filterEl);
  180. return;
  181. }
  182. const { items, multiple, selectionFollowsFocus } = this;
  183. if (items.length === 0) {
  184. return;
  185. }
  186. if (multiple) {
  187. return (_a = filterOutDisabled(items)[0]) === null || _a === void 0 ? void 0 : _a.setFocus();
  188. }
  189. const filtered = filterOutDisabled(items);
  190. const focusTarget = filtered.find((item) => item.selected) || filtered[0];
  191. if (selectionFollowsFocus && focusTarget) {
  192. focusTarget.selected = true;
  193. }
  194. return focusTarget.setFocus();
  195. }
  196. function setUpItems(tagName) {
  197. this.items = Array.from(this.el.querySelectorAll(tagName));
  198. let hasSelected = false;
  199. const { items } = this;
  200. items.forEach((item) => {
  201. item.icon = this.getIconType();
  202. if (!this.multiple) {
  203. item.disableDeselect = true;
  204. toggleSingleSelectItemTabbing(item, false);
  205. }
  206. if (item.selected) {
  207. hasSelected = true;
  208. toggleSingleSelectItemTabbing(item, true);
  209. this.selectedValues.set(item.value, item);
  210. }
  211. });
  212. const [first] = items;
  213. if (!hasSelected && first && !first.disabled) {
  214. toggleSingleSelectItemTabbing(first, true);
  215. }
  216. }
  217. function deselectRemovedItems() {
  218. const selectedValues = this.selectedValues;
  219. const itemValues = this.items.map(({ value }) => value);
  220. selectedValues.forEach((selectedItem) => {
  221. if (!itemValues.includes(selectedItem.value)) {
  222. this.selectedValues.delete(selectedItem.value);
  223. }
  224. });
  225. }
  226. function deselectSiblingItems(item) {
  227. this.items.forEach((currentItem) => {
  228. if (currentItem.value !== item.value) {
  229. currentItem.toggleSelected(false);
  230. if (this.selectedValues.has(currentItem.value)) {
  231. this.selectedValues.delete(currentItem.value);
  232. }
  233. }
  234. });
  235. }
  236. function selectSiblings(item, deselect = false) {
  237. if (!this.lastSelectedItem) {
  238. return;
  239. }
  240. const { items } = this;
  241. const start = items.findIndex((currentItem) => {
  242. return currentItem.value === this.lastSelectedItem.value;
  243. });
  244. const end = items.findIndex((currentItem) => {
  245. return currentItem.value === item.value;
  246. });
  247. items.slice(Math.min(start, end), Math.max(start, end)).forEach((currentItem) => {
  248. currentItem.toggleSelected(!deselect);
  249. if (!deselect) {
  250. this.selectedValues.set(currentItem.value, currentItem);
  251. }
  252. else {
  253. this.selectedValues.delete(currentItem.value);
  254. }
  255. });
  256. }
  257. let groups;
  258. function handleFilter(event) {
  259. const { filteredItems } = event.currentTarget;
  260. const values = filteredItems.map((item) => item.value);
  261. let hasSelectedMatch = false;
  262. if (!groups) {
  263. groups = new Set();
  264. }
  265. const matchedItems = this.items.filter((item) => {
  266. const parent = item.parentElement;
  267. const grouped = parent.matches("calcite-pick-list-group");
  268. if (grouped) {
  269. groups.add(parent);
  270. }
  271. const matches = values.includes(item.value);
  272. item.hidden = !matches;
  273. if (!hasSelectedMatch) {
  274. hasSelectedMatch = matches && item.selected;
  275. }
  276. return matches;
  277. });
  278. groups.forEach((group) => {
  279. const hasAtLeastOneMatch = matchedItems.some((item) => group.contains(item));
  280. group.hidden = !hasAtLeastOneMatch;
  281. if (!hasAtLeastOneMatch) {
  282. return;
  283. }
  284. const parentItem = getSlotted(group, "parent-item");
  285. if (parentItem) {
  286. parentItem.hidden = false;
  287. if (matchedItems.includes(parentItem)) {
  288. Array.from(group.children).forEach((child) => (child.hidden = false));
  289. }
  290. }
  291. });
  292. groups.clear();
  293. if (matchedItems.length > 0 && !hasSelectedMatch && !this.multiple) {
  294. toggleSingleSelectItemTabbing(matchedItems[0], true);
  295. }
  296. }
  297. function getItemData() {
  298. return this.items.map((item) => ({
  299. label: item.label,
  300. description: item.description,
  301. metadata: item.metadata,
  302. value: item.value
  303. }));
  304. }
  305. const CSS$1 = {
  306. sticky: "sticky-pos"
  307. };
  308. var ICON_TYPES;
  309. (function (ICON_TYPES) {
  310. ICON_TYPES["circle"] = "circle";
  311. ICON_TYPES["square"] = "square";
  312. ICON_TYPES["grip"] = "grip";
  313. })(ICON_TYPES || (ICON_TYPES = {}));
  314. const SLOTS$1 = {
  315. menuActions: "menu-actions"
  316. };
  317. var __rest = (undefined && undefined.__rest) || function (s, e) {
  318. var t = {};
  319. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
  320. t[p] = s[p];
  321. if (s != null && typeof Object.getOwnPropertySymbols === "function")
  322. for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
  323. if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
  324. t[p[i]] = s[p[i]];
  325. }
  326. return t;
  327. };
  328. const List = (_a) => {
  329. var { props: { disabled, loading, filterEnabled, dataForFilter, handleFilter, filterPlaceholder, setFilterEl } } = _a, rest = __rest(_a, ["props"]);
  330. const defaultSlot = h("slot", null);
  331. return (h(Host, Object.assign({ "aria-busy": toAriaBoolean(loading), role: "menu" }, rest),
  332. h("section", null,
  333. h("header", { class: { [CSS$1.sticky]: true } },
  334. filterEnabled ? (h("calcite-filter", { "aria-label": filterPlaceholder, disabled: loading || disabled, items: dataForFilter, onCalciteFilterChange: handleFilter, placeholder: filterPlaceholder, ref: setFilterEl })) : null,
  335. h("slot", { name: SLOTS$1.menuActions })),
  336. loading ? h("calcite-scrim", { loading: loading }) : null,
  337. defaultSlot)));
  338. };
  339. const CSS = {
  340. actions: "actions",
  341. actionsEnd: "actions--end",
  342. actionsStart: "actions--start",
  343. description: "description",
  344. handle: "handle",
  345. handleActivated: "handle--activated",
  346. highlight: "highlight",
  347. icon: "icon",
  348. iconDot: "icon-dot",
  349. label: "label",
  350. remove: "remove",
  351. title: "title",
  352. textContainer: "text-container"
  353. };
  354. const ICONS = {
  355. checked: "check",
  356. remove: "x"
  357. };
  358. const SLOTS = {
  359. actionsEnd: "actions-end",
  360. actionsStart: "actions-start"
  361. };
  362. const TEXT = {
  363. remove: "Remove"
  364. };
  365. export { CSS as C, HEADING_LEVEL as H, ICON_TYPES as I, List as L, SLOTS as S, TEXT as T, deselectSiblingItems as a, moveItemIndex as b, initializeObserver as c, deselectRemovedItems as d, cleanUpObserver as e, calciteListFocusOutHandler as f, getItemData as g, handleFilter as h, initialize as i, calciteListItemChangeHandler as j, keyDownHandler as k, calciteListItemValueChangeHandler as l, mutationObserverCallback as m, setUpItems as n, setFocus as o, SLOTS$2 as p, CSS$2 as q, removeItem as r, selectSiblings as s, ICONS as t };