forge-select 0.7.5 → 0.7.6

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/index.js CHANGED
@@ -307,7 +307,12 @@ var uidCounter = 0;
307
307
  var ForgeSelect = class {
308
308
  constructor(target, options = {}) {
309
309
  this.optionByValue = /* @__PURE__ */ new Map();
310
- this.optionByLabel = /* @__PURE__ */ new Map();
310
+ // Built on demand: only the allowCreate paths read it, and filling it eagerly
311
+ // normalizes every label (NFD + regex) at construction for the majority of
312
+ // selects that never create tags. rebuildOptionIndexes() nulls it, so every
313
+ // existing invalidation point — including an accentInsensitive change —
314
+ // already covers it.
315
+ this.optionByLabel = null;
311
316
  this.selected = [];
312
317
  this.selectedOptions = /* @__PURE__ */ new Map();
313
318
  this.suppressNextTagClick = false;
@@ -480,6 +485,7 @@ var ForgeSelect = class {
480
485
  if (this.opts.ajax && (this.opts.ajax.loadOnOpen ?? true) && !this.remoteLoaded) {
481
486
  this.scheduleRemoteLoad(this.query, 0);
482
487
  }
488
+ if (this.opts.allowCreate) this.labelIndex();
483
489
  this.renderList();
484
490
  this.positionDropdown();
485
491
  window.addEventListener("resize", this.onWindowResize);
@@ -1238,18 +1244,29 @@ var ForgeSelect = class {
1238
1244
  findOption(value) {
1239
1245
  return this.optionByValue.get(value);
1240
1246
  }
1247
+ /** Fills the label index on first use; see the field for why it is deferred. */
1248
+ labelIndex() {
1249
+ if (this.optionByLabel) return this.optionByLabel;
1250
+ const index = /* @__PURE__ */ new Map();
1251
+ const visit = (option) => {
1252
+ const label = normalizeSearchText(option.label, this.opts.accentInsensitive);
1253
+ if (!index.has(label)) index.set(label, option);
1254
+ option.children?.forEach(visit);
1255
+ };
1256
+ for (const item of this.data) (isGroup(item) ? item.options : [item]).forEach(visit);
1257
+ this.optionByLabel = index;
1258
+ return index;
1259
+ }
1241
1260
  findOptionByLabel(label) {
1242
- return this.optionByLabel.get(normalizeSearchText(label, this.opts.accentInsensitive));
1261
+ return this.labelIndex().get(normalizeSearchText(label, this.opts.accentInsensitive));
1243
1262
  }
1244
1263
  rebuildOptionIndexes() {
1245
1264
  this.optionByValue.clear();
1246
- this.optionByLabel.clear();
1265
+ this.optionByLabel = null;
1247
1266
  const duplicates = /* @__PURE__ */ new Set();
1248
1267
  const visit = (option) => {
1249
1268
  if (this.optionByValue.has(option.value)) duplicates.add(option.value);
1250
1269
  else this.optionByValue.set(option.value, option);
1251
- const label = normalizeSearchText(option.label, this.opts.accentInsensitive);
1252
- if (!this.optionByLabel.has(label)) this.optionByLabel.set(label, option);
1253
1270
  option.children?.forEach(visit);
1254
1271
  };
1255
1272
  for (const item of this.data) (isGroup(item) ? item.options : [item]).forEach(visit);