resources-8b3ba64a.js 12 KB

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