slim-select 4.0.6 → 4.1.0

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.
package/dist/sync.d.ts CHANGED
@@ -65,12 +65,20 @@ export default class SyncCoordinator {
65
65
  private applyChange;
66
66
  /**
67
67
  * Full sync: store → native <select> rebuild → render values + options.
68
- * Used when the option list itself changes (setData, native DOM edits, search results).
68
+ * Used when the option list itself changes (setData, native DOM edits).
69
+ * API search results update store + UI only — native select stays form/selection state.
69
70
  */
70
71
  private applyStructure;
72
+ /**
73
+ * Sync native <select> to current selection (form truth).
74
+ * When selected options are missing from the native DOM (e.g. picked from API
75
+ * search results), rebuild from selected options only — never from search hits.
76
+ */
77
+ private syncNativeSelection;
71
78
  /**
72
79
  * Lightweight selection sync: flip option.selected on native DOM only.
73
- * Avoids select.updateOptions() (innerHTML rebuild) for selection-only changes.
80
+ * Avoids select.updateOptions() (innerHTML rebuild) for selection-only changes
81
+ * when the options already exist on the native select.
74
82
  */
75
83
  private applySelection;
76
84
  /** Append a single option then full-sync native + render (same as legacy addOption). */
package/dist/vue/index.js CHANGED
@@ -341,7 +341,7 @@ var P = class {
341
341
  if (this.state === "closed" || this.state === "closing" || this.handlers.beforeClose && this.handlers.beforeClose(e) === !1) return !1;
342
342
  this.cancelPending();
343
343
  let t = ++this.generation;
344
- 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;
344
+ 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);
345
345
  }
346
346
  cancelPending() {
347
347
  this.generation++, this.animationAbort?.abort(), this.animationAbort = null, this.pendingTimer &&= (clearTimeout(this.pendingTimer), null);
@@ -407,16 +407,18 @@ var P = class {
407
407
  }
408
408
  validateDataArray(e) {
409
409
  if (!Array.isArray(e)) return /* @__PURE__ */ Error("Data must be an array");
410
- for (let t of e) if (t) if (t instanceof L || "label" in t) {
411
- if (!("label" in t)) return /* @__PURE__ */ Error("Optgroup must have a label");
412
- if ("options" in t && t.options) for (let e of t.options) {
413
- let t = this.validateOption(e);
414
- if (t) return t;
415
- }
416
- } else if (t instanceof I || "text" in t) {
417
- let e = this.validateOption(t);
418
- if (e) return e;
419
- } else return /* @__PURE__ */ Error("Data object must be a valid optgroup or option");
410
+ for (let t of e) if (t) {
411
+ if (t instanceof L || "label" in t) {
412
+ if (!("label" in t)) return /* @__PURE__ */ Error("Optgroup must have a label");
413
+ if ("options" in t && t.options) for (let e of t.options) {
414
+ let t = this.validateOption(e);
415
+ if (t) return t;
416
+ }
417
+ } else if (t instanceof I || "text" in t) {
418
+ let e = this.validateOption(t);
419
+ if (e) return e;
420
+ } else return /* @__PURE__ */ Error("Data object must be a valid optgroup or option");
421
+ }
420
422
  return null;
421
423
  }
422
424
  validateOption(e) {
@@ -556,10 +558,12 @@ var P = class {
556
558
  let a = [];
557
559
  if (i.options.forEach((i) => {
558
560
  (!e || e(i)) && (t ? a.push(n ? new I(i) : i) : r.push(n ? new I(i) : i));
559
- }), a.length > 0) if (n) {
560
- let e = new L(i);
561
- e.options = a, r.push(e);
562
- } else r.push(this.createOptgroupView(i, a));
561
+ }), a.length > 0) {
562
+ if (n) {
563
+ let e = new L(i);
564
+ e.options = a, r.push(e);
565
+ } else r.push(this.createOptgroupView(i, a));
566
+ }
563
567
  }
564
568
  i instanceof I && (!e || e(i)) && r.push(n ? new I(i) : i);
565
569
  }), r;
@@ -701,7 +705,7 @@ var P = class {
701
705
  close() {
702
706
  this.main.main.setAttribute("aria-expanded", "false"), this.main.arrow.path.setAttribute("d", this.classes.arrowClose);
703
707
  let e = this.modalSessionActive === !0;
704
- this.removeClasses(this.content.main, this.classes.contentOpen), e || (this.removeClasses(this.main.main, this.classes.dirAbove), this.removeClasses(this.main.main, this.classes.dirBelow)), e && this.modalElements && this.removeClasses(this.modalElements.overlay, this.classes.contentOpen), this.modalSessionActive = null, this.content.search.input.setAttribute("aria-hidden", "true"), this.main.main.removeAttribute("aria-activedescendant");
708
+ this.removeClasses(this.content.main, this.classes.contentOpen), e || (this.removeClasses(this.main.main, this.classes.dirAbove), this.removeClasses(this.main.main, this.classes.dirBelow)), e && this.modalElements && this.removeClasses(this.modalElements.overlay, this.classes.contentOpen), this.modalSessionActive = null, this.content.search.input.setAttribute("aria-hidden", "true"), this.main.main.removeAttribute("aria-activedescendant"), this.clearValueChipHighlight();
705
709
  }
706
710
  clearDirectionClasses() {
707
711
  this.removeClasses(this.main.main, this.classes.dirAbove), this.removeClasses(this.main.main, this.classes.dirBelow), this.removeClasses(this.content.main, this.classes.dirAbove), this.removeClasses(this.content.main, this.classes.dirBelow);
@@ -808,7 +812,8 @@ var P = class {
808
812
  if (t.length === 0) {
809
813
  this.main.values.innerHTML = this.placeholder().outerHTML;
810
814
  return;
811
- } else {
815
+ }
816
+ {
812
817
  let e = this.main.values.querySelector("." + this.classes.getFirst("placeholder"));
813
818
  e && e.remove();
814
819
  }
@@ -823,7 +828,8 @@ var P = class {
823
828
  let e = document.createElement("div");
824
829
  this.addClasses(e, this.classes.max), e.textContent = this.settings.maxValuesMessage.replace("{number}", t.length.toString()), this.main.values.innerHTML = e.outerHTML;
825
830
  return;
826
- } else {
831
+ }
832
+ {
827
833
  let e = this.main.values.querySelector("." + this.classes.getFirst("max"));
828
834
  e && e.remove();
829
835
  }
@@ -852,6 +858,38 @@ var P = class {
852
858
  let e = this.store.getSelectedOptions();
853
859
  return this.settings.keepOrder && (e = this.store.selectedOrderOptions(e)), e.slice(0, this.settings.minSelected).map((e) => e.id);
854
860
  }
861
+ getValueChips() {
862
+ return !this.settings.isMultiple || this.settings.multiString ? [] : Array.from(this.main.values.querySelectorAll("." + this.classes.getFirst("value"))).filter((e) => {
863
+ if (e.classList.contains(this.classes.getFirst("valueOut"))) return !1;
864
+ let t = e.querySelector("." + this.classes.getFirst("valueDelete"));
865
+ return !!t && !t.classList.contains(this.classes.getFirst("hide"));
866
+ });
867
+ }
868
+ getHighlightedValueChip() {
869
+ return this.getValueChips().find((e) => e.classList.contains(this.classes.getFirst("highlighted"))) ?? null;
870
+ }
871
+ clearValueChipHighlight() {
872
+ for (let e of Array.from(this.main.values.querySelectorAll("." + this.classes.getFirst("value")))) this.removeClasses(e, this.classes.highlighted);
873
+ }
874
+ highlightValueChip(e) {
875
+ this.clearValueChipHighlight(), e && this.addClasses(e, this.classes.highlighted);
876
+ }
877
+ navigateValueChips(e) {
878
+ let t = this.getValueChips();
879
+ if (t.length === 0) return !1;
880
+ let n = this.getHighlightedValueChip(), r = n ? t.indexOf(n) : -1;
881
+ return e === "left" ? (r === -1 ? this.highlightValueChip(t[t.length - 1]) : r > 0 && this.highlightValueChip(t[r - 1]), !0) : r !== -1 && (r < t.length - 1 ? this.highlightValueChip(t[r + 1]) : this.clearValueChipHighlight(), !0);
882
+ }
883
+ deleteValueChip(e = !1) {
884
+ let t = this.getValueChips();
885
+ if (t.length === 0) return !1;
886
+ let n = this.getHighlightedValueChip();
887
+ if (e && !n) return !1;
888
+ let r = n ?? t[t.length - 1], i = r.querySelector("." + this.classes.getFirst("valueDelete"));
889
+ if (!i) return !1;
890
+ let a = t.indexOf(r), o = n ? t[a - 1] ?? t[a + 1] ?? null : null;
891
+ return i.click(), o && o !== r && this.main.values.contains(o) ? this.highlightValueChip(o) : this.clearValueChipHighlight(), !0;
892
+ }
855
893
  updateMultipleValueDeleteVisibility() {
856
894
  if (!this.settings.isMultiple || this.settings.multiString) return;
857
895
  let e = !this.isAtMinSelected(), t = this.main.values.querySelectorAll("." + this.classes.getFirst("valueDelete"));
@@ -911,7 +949,8 @@ var P = class {
911
949
  if (this.settings.openPosition === "down") {
912
950
  this.moveContentBelow();
913
951
  return;
914
- } else if (this.settings.openPosition === "up") {
952
+ }
953
+ if (this.settings.openPosition === "up") {
915
954
  this.moveContentAbove();
916
955
  return;
917
956
  }
@@ -944,19 +983,27 @@ var P = class {
944
983
  main: e,
945
984
  input: t
946
985
  };
947
- if (this.settings.showSearch || (this.addClasses(e, this.classes.hide), t.readOnly = !0), t.type = "search", t.placeholder = this.settings.searchPlaceholder, t.tabIndex = -1, t.setAttribute("aria-label", this.settings.searchPlaceholder), t.setAttribute("aria-autocomplete", "list"), t.setAttribute("autocapitalize", "off"), t.setAttribute("autocomplete", "off"), t.setAttribute("autocorrect", "off"), t.setAttribute("aria-hidden", "true"), t.oninput = C((e) => {
948
- this.callbacks.search(e.target.value);
949
- }, 100), t.onkeydown = (e) => {
986
+ this.settings.showSearch || (this.addClasses(e, this.classes.hide), t.readOnly = !0), t.type = "search", t.placeholder = this.settings.searchPlaceholder, t.tabIndex = -1, t.setAttribute("aria-label", this.settings.searchPlaceholder), t.setAttribute("aria-autocomplete", "list"), t.setAttribute("autocapitalize", "off"), t.setAttribute("autocomplete", "off"), t.setAttribute("autocorrect", "off"), t.setAttribute("aria-hidden", "true");
987
+ let i = C(() => {
988
+ this.callbacks.search(t.value);
989
+ }, 100);
990
+ if (t.oninput = (e) => {
991
+ e.target.value !== "" && this.clearValueChipHighlight(), i();
992
+ }, t.onkeydown = (e) => {
950
993
  switch (e.key) {
951
994
  case "ArrowUp":
952
- case "ArrowDown": return e.key === "ArrowDown" ? this.highlight("down") : this.highlight("up"), !1;
995
+ case "ArrowDown": return this.clearValueChipHighlight(), e.key === "ArrowDown" ? this.highlight("down") : this.highlight("up"), !1;
996
+ case "ArrowLeft":
997
+ case "ArrowRight": return t.value !== "" || !this.navigateValueChips(e.key === "ArrowLeft" ? "left" : "right") || (e.preventDefault(), !1);
998
+ case "Backspace": return t.value !== "" || !this.deleteValueChip() || (e.preventDefault(), !1);
999
+ case "Delete": return t.value !== "" || !this.getHighlightedValueChip() || !this.deleteValueChip(!0) || (e.preventDefault(), !1);
953
1000
  case "Tab": return this.requestClose("tab"), !0;
954
1001
  case "Escape": return this.requestClose("escape"), !1;
955
1002
  case "Enter":
956
- let t = this.content.list.querySelector("." + this.classes.getFirst("highlighted"));
957
- return t ? (t.click(), !1) : this.callbacks.addable ? (n.click(), !1) : !0;
1003
+ let r = this.content.list.querySelector("." + this.classes.getFirst("highlighted"));
1004
+ return r ? (r.click(), !1) : !this.callbacks.addable || (n.click(), !1);
958
1005
  }
959
- return !0;
1006
+ return e.key.length === 1 && this.clearValueChipHighlight(), !0;
960
1007
  }, e.appendChild(t), this.callbacks.addable) {
961
1008
  this.addClasses(n, this.classes.addable);
962
1009
  let t = document.createElementNS("http://www.w3.org/2000/svg", "svg");
@@ -982,7 +1029,7 @@ var P = class {
982
1029
  }, e);
983
1030
  }
984
1031
  }, r = this.callbacks.addable(t);
985
- r === !1 || r == null || (r instanceof Promise ? r.then((e) => {
1032
+ r !== !1 && r != null && (r instanceof Promise ? r.then((e) => {
986
1033
  typeof e == "string" ? n({
987
1034
  text: e,
988
1035
  value: e
@@ -1106,7 +1153,8 @@ var P = class {
1106
1153
  });
1107
1154
  this.callbacks.setSelected(e, !0);
1108
1155
  return;
1109
- } else {
1156
+ }
1157
+ {
1110
1158
  let e = n.options.map((e) => e.id).filter((e) => e !== void 0), r = t.concat(e);
1111
1159
  for (let e of n.options) e.id && !this.store.getOptionByID(e.id) && this.callbacks.addOption(new I(e));
1112
1160
  this.callbacks.setSelected(r, !0);
@@ -1550,6 +1598,11 @@ var V = class {
1550
1598
  getSelectedValues() {
1551
1599
  return this.getSelectedOptions().map((e) => e.value);
1552
1600
  }
1601
+ hasOptionValues(e) {
1602
+ if (e.length === 0) return !0;
1603
+ let t = new Set(Array.from(this.select.options).map((e) => e.value));
1604
+ return e.every((e) => t.has(e));
1605
+ }
1553
1606
  setSelected(e) {
1554
1607
  this.changeListen(!1);
1555
1608
  let t = this.select.childNodes;
@@ -1594,13 +1647,14 @@ var V = class {
1594
1647
  })), this.changeListen(!0);
1595
1648
  }
1596
1649
  updateOptions(e) {
1597
- if (!(!e || e.length === 0)) {
1598
- this.isUpdating = !0, this.pendingOptionsChange = null, this.changeListen(!1), this.select.innerHTML = "";
1599
- for (let t of e) t instanceof L && this.select.appendChild(this.createOptgroup(t)), t instanceof I && this.select.appendChild(this.createOption(t));
1600
- if (this.select.dispatchEvent(new Event("change", { bubbles: !0 })), this.changeListen(!0), this.isUpdating = !1, this.pendingOptionsChange !== null) {
1601
- let e = this.pendingOptionsChange;
1602
- e.length > 0 && this.onOptionsChange ? (this.pendingOptionsChange = null, this.changeListen(!1), this.onOptionsChange(e), this.changeListen(!0)) : this.pendingOptionsChange = null;
1603
- }
1650
+ if (!e || e.length === 0) return;
1651
+ this.isUpdating = !0, this.pendingOptionsChange = null, this.changeListen(!1);
1652
+ let t = this.getSelectedValues();
1653
+ this.select.innerHTML = "";
1654
+ for (let t of e) t instanceof L && this.select.appendChild(this.createOptgroup(t)), t instanceof I && this.select.appendChild(this.createOption(t));
1655
+ if (w(t, this.getSelectedValues()) || this.select.dispatchEvent(new Event("change", { bubbles: !0 })), this.changeListen(!0), this.isUpdating = !1, this.pendingOptionsChange !== null) {
1656
+ let e = this.pendingOptionsChange;
1657
+ e.length > 0 && this.onOptionsChange ? (this.pendingOptionsChange = null, this.changeListen(!1), this.onOptionsChange(e), this.changeListen(!0)) : this.pendingOptionsChange = null;
1604
1658
  }
1605
1659
  }
1606
1660
  createOptgroup(e) {
@@ -1717,9 +1771,7 @@ var W = class {
1717
1771
  case "selection":
1718
1772
  this.applySelection(e.values, e.source, e.runAfterChange !== !1);
1719
1773
  break;
1720
- case "addOption":
1721
- this.applyAddOption(e.option);
1722
- break;
1774
+ case "addOption": this.applyAddOption(e.option);
1723
1775
  }
1724
1776
  }
1725
1777
  applyStructure(e, t, n = !1, r = !1) {
@@ -1732,12 +1784,30 @@ var W = class {
1732
1784
  }
1733
1785
  i.setData(e, n);
1734
1786
  let u = i.getData(!1);
1735
- r || i.snapshotCatalog(), a.updateOptions(u), o.renderValues(), o.renderOptions(u), s.afterChange && !w(c, i.getSelected()) && s.afterChange(i.getSelectedOptions());
1787
+ r || i.snapshotCatalog(), r || a.updateOptions(u), o.renderValues(), o.renderOptions(u), s.afterChange && !w(c, i.getSelected()) && s.afterChange(i.getSelectedOptions());
1788
+ }
1789
+ syncNativeSelection() {
1790
+ let { store: e, select: t } = this.deps, n = e.getSelectedOptions(), r = e.getSelectedValues();
1791
+ if (!t.hasOptionValues(r)) {
1792
+ if (n.length > 0) {
1793
+ t.updateOptions(n);
1794
+ return;
1795
+ }
1796
+ let r = e.getCatalogData().find((e) => e instanceof I && e.placeholder === !0);
1797
+ if (r) {
1798
+ t.updateOptions([new I({
1799
+ ...r,
1800
+ selected: !0
1801
+ })]);
1802
+ return;
1803
+ }
1804
+ }
1805
+ t.setSelectedByValue(r);
1736
1806
  }
1737
1807
  applySelection(e, t, n) {
1738
1808
  let { store: r, select: i, render: a, events: o } = this.deps, s = r.getSelected(), c = U(r, e);
1739
1809
  if (w(s, c)) return;
1740
- r.setSelectedBy("id", c), i.setSelectedByValue(r.getSelectedValues()), a.renderValues();
1810
+ r.setSelectedBy("id", c), this.syncNativeSelection(), a.renderValues();
1741
1811
  let l = a.content.search.input.value.trim();
1742
1812
  l === "" ? a.canUpdateOptionSelectionInPlace() ? a.updateOptionSelection() : a.renderOptions(r.getData(!1)) : a.hasRenderedOptions() ? a.updateOptionSelection() : this.deps.search && this.deps.search(l), n && o.afterChange && !w(s, r.getSelected()) && o.afterChange(r.getSelectedOptions());
1743
1813
  }
@@ -1752,12 +1822,18 @@ var W = class {
1752
1822
  }
1753
1823
  return !1;
1754
1824
  };
1755
- if (!c(t.getData(!1))) if (o) {
1756
- let n = t.getCatalogData();
1757
- c(n) || t.setData([...n, new I(e)], !0), t.snapshotCatalog();
1758
- } else t.addOption(e), t.snapshotCatalog();
1825
+ if (!c(t.getData(!1))) {
1826
+ if (o) {
1827
+ let n = t.getCatalogData();
1828
+ c(n) || t.setData([...n, new I(e)], !0), t.snapshotCatalog();
1829
+ } else t.addOption(e), t.snapshotCatalog();
1830
+ }
1759
1831
  let l = t.getData(!1);
1760
- n.updateOptions(l), r.renderValues(), r.renderOptions(l), i.afterChange && !w(a, t.getSelected()) && i.afterChange(t.getSelectedOptions());
1832
+ if (o) {
1833
+ let e = t.getSelectedOptions();
1834
+ e.length > 0 && n.updateOptions(e);
1835
+ } else n.updateOptions(l);
1836
+ r.renderValues(), r.renderOptions(l), i.afterChange && !w(a, t.getSelected()) && i.afterChange(t.getSelectedOptions());
1761
1837
  }
1762
1838
  }, G = class {
1763
1839
  selectEl;