slim-select 4.0.3 → 4.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -333,11 +333,14 @@ var O = class {
333
333
  }
334
334
  this.state = "open", this.handlers.afterOpen && this.handlers.afterOpen(), this.handlers.onOpenReady && this.handlers.onOpenReady();
335
335
  }
336
- async requestClose() {
337
- if (this.state === "closed" || this.state === "closing") return;
336
+ async requestClose(e = {
337
+ source: "api",
338
+ selectionChanged: !1
339
+ }) {
340
+ if (this.state === "closed" || this.state === "closing" || this.handlers.beforeClose && this.handlers.beforeClose(e) === !1) return !1;
338
341
  this.cancelPending();
339
- let e = ++this.generation;
340
- this.handlers.beforeClose && this.handlers.beforeClose(), this.state = "closing", await this.waitForPhase("close", e), e === this.generation && (this.state = "closed", this.handlers.afterClose && this.handlers.afterClose(), this.handlers.onCloseReady && this.handlers.onCloseReady());
342
+ let t = ++this.generation;
343
+ return this.handlers.onClose && this.handlers.onClose(e), this.state = "closing", await this.waitForPhase("close", t), t === this.generation ? (this.state = "closed", this.handlers.afterClose && this.handlers.afterClose(), this.handlers.onCloseReady && this.handlers.onCloseReady(), !0) : !1;
341
344
  }
342
345
  cancelPending() {
343
346
  this.generation++, this.animationAbort?.abort(), this.animationAbort = null, this.pendingTimer &&= (clearTimeout(this.pendingTimer), null);
@@ -596,6 +599,24 @@ var O = class {
596
599
  constructor(e, t, n, r) {
597
600
  this.store = n, this.settings = e, this.classes = t, this.callbacks = r, this.lastSelectedOption = null, this.lastRenderedOptions = [], this.main = this.mainDiv(), this.content = this.contentDiv(), this.updateClassStyles(), this.updateAriaAttributes(), this.settings.contentPosition !== "relative" && (this.content.main.style.top = "-9999px", this.content.main.style.left = "-9999px", this.content.main.style.margin = "0", this.content.main.style.width = "auto"), this.settings.contentLocation && this.settings.contentLocation.appendChild(this.content.main), this.settings.modal !== "off" && !this.settings.alwaysOpen && (this.modalElements = this.createModalElements(), document.body.appendChild(this.modalElements.overlay));
598
601
  }
602
+ requestClose(e, t) {
603
+ this.callbacks.close({
604
+ source: e,
605
+ option: t?.option,
606
+ selectionChanged: t?.selectionChanged ?? !1
607
+ });
608
+ }
609
+ selectionChanged(e, t) {
610
+ if (e.length !== t.length) return !0;
611
+ let n = e.map((e) => e.id).sort(), r = t.map((e) => e.id).sort();
612
+ return n.some((e, t) => e !== r[t]);
613
+ }
614
+ closeOnSingleSelectReclick(e) {
615
+ this.settings.closeOnSelect && this.requestClose("select", {
616
+ option: e,
617
+ selectionChanged: !1
618
+ });
619
+ }
599
620
  addClasses(e, t) {
600
621
  if (!t || t.trim() === "") return;
601
622
  let n = t.split(" ").filter((e) => e.trim() !== "");
@@ -641,13 +662,13 @@ var O = class {
641
662
  this.settings.modalTitle ? (n = document.createElement("div"), this.addClasses(n, this.classes.modalTitle), n.id = `${this.settings.id}-modal-title`, n.textContent = this.settings.modalTitle, t.setAttribute("aria-labelledby", n.id)) : t.setAttribute("aria-label", this.settings.ariaLabel);
642
663
  let r = document.createElement("button");
643
664
  r.type = "button", this.addClasses(r, this.classes.modalClose), r.setAttribute("aria-label", "Close"), r.onclick = (e) => {
644
- e.stopPropagation(), this.callbacks.close();
665
+ e.stopPropagation(), this.requestClose("modal");
645
666
  };
646
667
  let i = document.createElementNS("http://www.w3.org/2000/svg", "svg");
647
668
  i.setAttribute("viewBox", "0 0 100 100");
648
669
  let a = document.createElementNS("http://www.w3.org/2000/svg", "path");
649
670
  return a.setAttribute("d", this.classes.deselectPath), i.appendChild(a), r.appendChild(i), e.onclick = (t) => {
650
- t.target === e && this.callbacks.close();
671
+ t.target === e && this.requestClose("modal");
651
672
  }, n && t.appendChild(n), e.appendChild(t), {
652
673
  overlay: e,
653
674
  dialog: t,
@@ -698,17 +719,17 @@ var O = class {
698
719
  switch (e.key) {
699
720
  case "ArrowUp":
700
721
  case "ArrowDown": return this.callbacks.open(), e.key === "ArrowDown" ? this.highlight("down") : this.highlight("up"), !1;
701
- case "Tab": return this.callbacks.close(), !0;
722
+ case "Tab": return this.requestClose("tab"), !0;
702
723
  case "Enter":
703
724
  case " ":
704
725
  this.callbacks.open();
705
726
  let t = this.content.list.querySelector("." + this.classes.getFirst("highlighted"));
706
727
  return t && t.click(), !1;
707
- case "Escape": return this.callbacks.close(), !1;
728
+ case "Escape": return this.requestClose("escape"), !1;
708
729
  }
709
730
  return e.key.length === 1 && this.callbacks.open(), !0;
710
731
  }, e.onclick = (e) => {
711
- this.settings.disabled || (this.settings.isOpen ? this.callbacks.close() : this.callbacks.open());
732
+ this.settings.disabled || (this.settings.isOpen ? this.requestClose("toggle") : this.callbacks.open());
712
733
  };
713
734
  let t = document.createElement("div");
714
735
  this.addClasses(t, this.classes.values), e.appendChild(t);
@@ -730,7 +751,7 @@ var O = class {
730
751
  let e = this.store.getFirstOption(), t = e ? e.id : "";
731
752
  this.callbacks.setSelected(t, !1);
732
753
  }
733
- this.settings.closeOnSelect && this.callbacks.close(), this.callbacks.afterChange && this.callbacks.afterChange(this.store.getSelectedOptions());
754
+ this.settings.closeOnSelect && this.requestClose("deselect", { selectionChanged: !0 }), this.callbacks.afterChange && this.callbacks.afterChange(this.store.getSelectedOptions());
734
755
  }
735
756
  }, n.onkeydown = (e) => {
736
757
  (e.key === "Enter" || e.key === " ") && (e.preventDefault(), n.click());
@@ -850,7 +871,7 @@ var O = class {
850
871
  if (t instanceof j) for (let n of t.options) n.id && e.push(n.id);
851
872
  t instanceof A && e.push(t.id);
852
873
  }
853
- this.callbacks.setSelected(e, !1), this.settings.closeOnSelect && this.callbacks.close(), this.callbacks.afterChange && this.callbacks.afterChange(i), this.updateDeselectAll(), this.updateMultipleValueDeleteVisibility();
874
+ this.callbacks.setSelected(e, !1), this.settings.closeOnSelect && this.requestClose("deselect", { selectionChanged: !0 }), this.callbacks.afterChange && this.callbacks.afterChange(i), this.updateDeselectAll(), this.updateMultipleValueDeleteVisibility();
854
875
  }
855
876
  };
856
877
  let r = document.createElementNS("http://www.w3.org/2000/svg", "svg");
@@ -928,8 +949,8 @@ var O = class {
928
949
  switch (e.key) {
929
950
  case "ArrowUp":
930
951
  case "ArrowDown": return e.key === "ArrowDown" ? this.highlight("down") : this.highlight("up"), !1;
931
- case "Tab": return this.callbacks.close(), !0;
932
- case "Escape": return this.callbacks.close(), !1;
952
+ case "Tab": return this.requestClose("tab"), !0;
953
+ case "Escape": return this.requestClose("escape"), !1;
933
954
  case "Enter":
934
955
  let t = this.content.list.querySelector("." + this.classes.getFirst("highlighted"));
935
956
  return t ? (t.click(), !1) : this.callbacks.addable ? (n.click(), !1) : !0;
@@ -956,7 +977,7 @@ var O = class {
956
977
  if (this.callbacks.search(""), this.settings.closeOnSelect) {
957
978
  let e = i(this.content.main);
958
979
  setTimeout(() => {
959
- this.callbacks.close();
980
+ this.requestClose("select", { selectionChanged: !0 });
960
981
  }, e);
961
982
  }
962
983
  }, r = this.callbacks.addable(t);
@@ -1239,23 +1260,35 @@ var O = class {
1239
1260
  t.classList.add(e);
1240
1261
  }), e.style && (t.style.cssText = e.style), this.setOptionElementContent(t, e, this.content.search.input.value), e.display || this.addClasses(t, this.classes.hide), e.disabled && this.addClasses(t, this.classes.disabled), e.selected && this.settings.hideSelected && this.addClasses(t, this.classes.hide), e.selected ? (this.addClasses(t, this.classes.selected), t.setAttribute("aria-selected", "true"), this.main.main.setAttribute("aria-activedescendant", t.id)) : (this.removeClasses(t, this.classes.selected), t.setAttribute("aria-selected", "false")), t.addEventListener("click", (t) => {
1241
1262
  t.preventDefault(), t.stopPropagation();
1242
- let n = this.store.getSelected(), r = t.currentTarget, i = String(r.dataset.id), a = t.ctrlKey || t.metaKey;
1243
- if (e.disabled || !this.settings.isMultiple && e.selected && !this.settings.allowDeselect || e.selected && e.mandatory || this.settings.isMultiple && this.settings.maxSelected <= n.length && !e.selected || this.settings.isMultiple && this.settings.minSelected >= n.length && e.selected && !a) return;
1244
- let o = !1, s = this.store.getSelectedOptions(), c = [];
1263
+ let n = this.store.getSelected(), r = t.currentTarget, i = String(r.dataset.id), a = this.store.getOptionByID(i) ?? e, o = n.includes(i), s = t.ctrlKey || t.metaKey;
1264
+ if (e.disabled) return;
1265
+ if (!this.settings.isMultiple && o && !this.settings.allowDeselect) {
1266
+ this.closeOnSingleSelectReclick(a);
1267
+ return;
1268
+ }
1269
+ if (o && a.mandatory) {
1270
+ this.closeOnSingleSelectReclick(a);
1271
+ return;
1272
+ }
1273
+ if (this.settings.isMultiple && this.settings.maxSelected <= n.length && !o || this.settings.isMultiple && this.settings.minSelected >= n.length && o && !s) return;
1274
+ let c = !1, l = this.store.getSelectedOptions(), u = [];
1245
1275
  if (this.settings.isMultiple) {
1246
- let n = s.some((e) => e.id === i);
1276
+ let n = l.some((e) => e.id === i);
1247
1277
  if (t.shiftKey && this.lastSelectedOption) {
1248
1278
  let t = this.lastRenderedOptions, n = t.findIndex((e) => e.id === this.lastSelectedOption.id), r = t.findIndex((t) => t.id === e.id);
1249
1279
  if (n >= 0 && r >= 0) {
1250
- let e = Math.min(n, r), i = Math.max(n, r), a = t.slice(e, i + 1).filter((e) => !s.find((t) => t.id === e.id));
1251
- c = s.length + a.length <= this.settings.maxSelected ? s.concat(a) : s;
1252
- } else c = s;
1253
- } else c = n ? s.filter((e) => e.id !== i) : s.concat(e), this.lastSelectedOption = e;
1280
+ let e = Math.min(n, r), i = Math.max(n, r), a = t.slice(e, i + 1).filter((e) => !l.find((t) => t.id === e.id));
1281
+ u = l.length + a.length <= this.settings.maxSelected ? l.concat(a) : l;
1282
+ } else u = l;
1283
+ } else u = n ? l.filter((e) => e.id !== i) : l.concat(a), this.lastSelectedOption = a;
1254
1284
  }
1255
- if (this.settings.isMultiple || (c = e.selected ? [] : [e]), this.callbacks.beforeChange || (o = !0), this.callbacks.beforeChange && (o = this.callbacks.beforeChange(c, s) !== !1), o) {
1256
- this.store.getOptionByID(i) || this.callbacks.addOption(e), this.callbacks.setSelected(c.map((e) => e.id), !1);
1285
+ if (this.settings.isMultiple || (u = o ? [] : [a]), this.callbacks.beforeChange || (c = !0), this.callbacks.beforeChange && (c = this.callbacks.beforeChange(u, l) !== !1), c) {
1286
+ this.store.getOptionByID(i) || this.callbacks.addOption(e), this.callbacks.setSelected(u.map((e) => e.id), !1);
1257
1287
  let n = t.ctrlKey || t.metaKey || t.shiftKey;
1258
- this.settings.closeOnSelect && !(this.settings.isMultiple && n) && this.callbacks.close(), this.callbacks.afterChange && this.callbacks.afterChange(c);
1288
+ this.settings.closeOnSelect && !(this.settings.isMultiple && n) && this.requestClose("select", {
1289
+ option: a,
1290
+ selectionChanged: this.selectionChanged(l, u)
1291
+ }), this.callbacks.afterChange && this.callbacks.afterChange(u);
1259
1292
  }
1260
1293
  }), t;
1261
1294
  }
@@ -1760,7 +1793,6 @@ var R = class {
1760
1793
  let n = [
1761
1794
  "beforeOpen",
1762
1795
  "afterOpen",
1763
- "beforeClose",
1764
1796
  "afterClose"
1765
1797
  ];
1766
1798
  for (let e in t.events) t.events.hasOwnProperty(e) && (n.indexOf(e) === -1 ? this.events[e] = t.events[e] : this.events[e] = _(t.events[e], 100));
@@ -1769,7 +1801,10 @@ var R = class {
1769
1801
  }, this.select.onDisabledChange = (e) => {
1770
1802
  e ? this.disable() : this.enable();
1771
1803
  }, this.select.onLabelClick = () => {
1772
- this.settings.disabled || (this.settings.isOpen ? this.close() : this.open());
1804
+ this.settings.disabled || (this.settings.isOpen ? this.close({
1805
+ source: "toggle",
1806
+ selectionChanged: !1
1807
+ }) : this.open());
1773
1808
  };
1774
1809
  let r = t.data ? t.data : this.select.getData();
1775
1810
  this.store = new M(this.settings.isMultiple ? "multiple" : "single", r), t.data && this.select.updateOptions(this.store.getData());
@@ -1817,7 +1852,8 @@ var R = class {
1817
1852
  }, this.lifecycle = new k({
1818
1853
  beforeOpen: this.events.beforeOpen,
1819
1854
  afterOpen: this.events.afterOpen,
1820
- beforeClose: this.events.beforeClose,
1855
+ beforeClose: (e) => this.events.beforeClose?.(e),
1856
+ onClose: (e) => this.applyClose(e),
1821
1857
  afterClose: () => {
1822
1858
  this.render.clearDirectionClasses(), this.render.finalizeModalClose(), this.events.afterClose && this.events.afterClose();
1823
1859
  },
@@ -1835,7 +1871,10 @@ var R = class {
1835
1871
  !this.settings.isOpen && !this.settings.isFullOpen || this.render.moveContent();
1836
1872
  },
1837
1873
  onVisibilityChange: () => {
1838
- document.hidden && this.close();
1874
+ document.hidden && this.close({
1875
+ source: "api",
1876
+ selectionChanged: !1
1877
+ });
1839
1878
  }
1840
1879
  }), this.render.renderValues(), this.render.renderOptions(this.store.getData(!1));
1841
1880
  let o = this.selectEl.getAttribute("aria-label"), s = this.selectEl.getAttribute("aria-labelledby");
@@ -1890,10 +1929,18 @@ var R = class {
1890
1929
  let e = this.render.content.search.input.value.trim();
1891
1930
  e !== "" && this.search(e);
1892
1931
  }
1893
- close(e = null) {
1894
- !this.settings.isOpen || this.settings.alwaysOpen || (this.lifecycle.cancelPending(), this.render.close(), !this.settings.keepSearch && this.render.content.search.input.value !== "" && (this.sync.flush(), this.search("")), this.render.mainFocus(e), this.settings.isOpen = !1, this.settings.isFullOpen = !1, this.lifecycle.requestClose().then(() => {
1895
- this.settings.isOpen || (this.settings.isOpen = this.lifecycle.isOpen, this.settings.isFullOpen = this.lifecycle.isFullOpen);
1896
- }), this.render.stopPositionTracking());
1932
+ close(e = {
1933
+ source: "api",
1934
+ selectionChanged: !1
1935
+ }) {
1936
+ !this.settings.isOpen || this.settings.alwaysOpen || this.lifecycle.requestClose(e).then((e) => {
1937
+ e && (this.settings.isOpen || (this.settings.isOpen = this.lifecycle.isOpen, this.settings.isFullOpen = this.lifecycle.isFullOpen));
1938
+ });
1939
+ }
1940
+ applyClose(e) {
1941
+ this.render.close(), !this.settings.keepSearch && this.render.content.search.input.value !== "" && (this.sync.flush(), this.search(""));
1942
+ let t = e.source === "outside" || e.source === "toggle";
1943
+ this.render.mainFocus(t ? "click" : null), this.settings.isOpen = !1, this.settings.isFullOpen = !1, this.render.stopPositionTracking();
1897
1944
  }
1898
1945
  search(e) {
1899
1946
  let t = e.trim();
@@ -1955,7 +2002,10 @@ var R = class {
1955
2002
  this.lifecycle.destroy(), this.render.stopPositionTracking(), this.globalEvents.detach({ listenScroll: this.settings.openPosition === "auto" }), this.store.setData([]), this.render.destroy(), this.select.destroy(), delete this.selectEl.slim;
1956
2003
  }
1957
2004
  documentClick(e) {
1958
- this.settings.isOpen && e.target && !g(e.target, this.settings.id) && this.close(e.type);
2005
+ this.settings.isOpen && e.target && !g(e.target, this.settings.id) && this.close({
2006
+ source: "outside",
2007
+ selectionChanged: !1
2008
+ });
1959
2009
  }
1960
2010
  };
1961
2011
  //#endregion