forge-select 0.7.3 → 0.7.5
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/README.md +11 -0
- package/dist/index.cjs +35 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.global.js +1 -1
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +35 -33
- package/dist/index.js.map +1 -1
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -205,6 +205,17 @@ Forge Select is vanilla TypeScript/JavaScript, so it can be mounted inside any f
|
|
|
205
205
|
|
|
206
206
|
Forge Select is designed as a drop-in-concept replacement for Select2: no jQuery dependency, native accessibility, and a smaller API surface. A full option/event/method mapping table and a step-by-step migration checklist are available in [`docs/migration-from-select2.md`](./docs/migration-from-select2.md).
|
|
207
207
|
|
|
208
|
+
## Bundle size
|
|
209
|
+
|
|
210
|
+
Forge Select ships as a single class, so **the whole feature set is in the bundle whether or not you use it** — tree select, AJAX, tags, sortable tags and virtualization cannot be tree-shaken away. Measured with esbuild (minified + gzipped):
|
|
211
|
+
|
|
212
|
+
| Usage | JS |
|
|
213
|
+
| --------------------------------------------------------------- | ------- |
|
|
214
|
+
| Minimal — `new ForgeSelect(el, { placeholder })` | 13.3 KB |
|
|
215
|
+
| Every feature — tree, AJAX, tags, sortable, measured rows, etc. | 13.4 KB |
|
|
216
|
+
|
|
217
|
+
Plus 1.7 KB gzipped for `forge-select/styles.css`. Budget ~15 KB gzipped total and the number won't move as you adopt more of the API. Splitting the core into opt-in subpath entrypoints is under consideration for a future major version; it is not planned as a patch, since it would change the public import surface.
|
|
218
|
+
|
|
208
219
|
## Benchmarks
|
|
209
220
|
|
|
210
221
|
Run `npm run bench` for a reproducible JSON baseline covering bundle size, initialization, 10,000-option search latency, and virtual-scroll performance. The methodology and result fields are documented in [`docs/benchmarks.md`](./docs/benchmarks.md).
|
package/dist/index.cjs
CHANGED
|
@@ -543,22 +543,20 @@ var ForgeSelect = class {
|
|
|
543
543
|
}
|
|
544
544
|
this.typeaheadBuffer = "";
|
|
545
545
|
this.highlightedIndex = -1;
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
this.ajaxTimer = null;
|
|
555
|
-
}
|
|
556
|
-
this.ajaxController?.abort();
|
|
557
|
-
this.ajaxController = null;
|
|
558
|
-
this.setLoading(false);
|
|
559
|
-
this.loadingMore = false;
|
|
560
|
-
this.remoteLoaded = false;
|
|
546
|
+
const hadQuery = this.query !== "";
|
|
547
|
+
if (this.searchInput) this.searchInput.value = "";
|
|
548
|
+
this.query = "";
|
|
549
|
+
if (hadQuery && this.opts.ajax) {
|
|
550
|
+
this.ajaxRequestId += 1;
|
|
551
|
+
if (this.ajaxTimer) {
|
|
552
|
+
clearTimeout(this.ajaxTimer);
|
|
553
|
+
this.ajaxTimer = null;
|
|
561
554
|
}
|
|
555
|
+
this.ajaxController?.abort();
|
|
556
|
+
this.ajaxController = null;
|
|
557
|
+
this.setLoading(false);
|
|
558
|
+
this.loadingMore = false;
|
|
559
|
+
this.remoteLoaded = false;
|
|
562
560
|
}
|
|
563
561
|
this.emitter.emit("close");
|
|
564
562
|
for (const plugin of this.plugins) plugin.onClose?.(this);
|
|
@@ -654,16 +652,17 @@ var ForgeSelect = class {
|
|
|
654
652
|
if (options.beforeCreate !== void 0) this.opts.beforeCreate = options.beforeCreate;
|
|
655
653
|
if (options.createOption !== void 0) this.opts.createOption = options.createOption;
|
|
656
654
|
if (options.missingSelectionPolicy !== void 0) this.opts.missingSelectionPolicy = options.missingSelectionPolicy;
|
|
655
|
+
let needsReindex = false;
|
|
657
656
|
if (options.duplicateValuePolicy !== void 0) {
|
|
658
657
|
this.opts.duplicateValuePolicy = options.duplicateValuePolicy;
|
|
659
|
-
|
|
658
|
+
needsReindex = true;
|
|
660
659
|
}
|
|
661
660
|
if (options.filterOption !== void 0) this.opts.filterOption = options.filterOption;
|
|
662
661
|
if (options.searchFields !== void 0) this.opts.searchFields = options.searchFields;
|
|
663
662
|
if (options.tokenSearch !== void 0) this.opts.tokenSearch = options.tokenSearch;
|
|
664
663
|
if (options.accentInsensitive !== void 0) {
|
|
665
664
|
this.opts.accentInsensitive = options.accentInsensitive;
|
|
666
|
-
|
|
665
|
+
needsReindex = true;
|
|
667
666
|
}
|
|
668
667
|
if (options.searchScorer !== void 0) this.opts.searchScorer = options.searchScorer;
|
|
669
668
|
if (options.highlightSearch !== void 0) this.opts.highlightSearch = options.highlightSearch;
|
|
@@ -690,6 +689,7 @@ var ForgeSelect = class {
|
|
|
690
689
|
if (options.disabled) this.disable();
|
|
691
690
|
else this.enable();
|
|
692
691
|
}
|
|
692
|
+
if (needsReindex) this.rebuildOptionIndexes();
|
|
693
693
|
this.root.classList.toggle("forge-select--sortable", this.opts.sortable && this.opts.multiple);
|
|
694
694
|
this.updateSearchVisibility();
|
|
695
695
|
this.clearRowCaches();
|
|
@@ -741,20 +741,6 @@ var ForgeSelect = class {
|
|
|
741
741
|
* the same fallback used for values selected from a stale ajax page).
|
|
742
742
|
*/
|
|
743
743
|
setData(data) {
|
|
744
|
-
if (this.ajaxTimer) {
|
|
745
|
-
clearTimeout(this.ajaxTimer);
|
|
746
|
-
this.ajaxTimer = null;
|
|
747
|
-
}
|
|
748
|
-
this.ajaxController?.abort();
|
|
749
|
-
this.ajaxController = null;
|
|
750
|
-
this.ajaxRequestId += 1;
|
|
751
|
-
this.setLoading(false);
|
|
752
|
-
this.loadingMore = false;
|
|
753
|
-
this.loadError = null;
|
|
754
|
-
this.remoteLoaded = true;
|
|
755
|
-
this.page = 0;
|
|
756
|
-
this.hasMore = false;
|
|
757
|
-
this.nextCursor = void 0;
|
|
758
744
|
const previousData = this.data;
|
|
759
745
|
this.data = data;
|
|
760
746
|
try {
|
|
@@ -770,6 +756,20 @@ var ForgeSelect = class {
|
|
|
770
756
|
this.rebuildOptionIndexes();
|
|
771
757
|
throw new Error(`ForgeSelect: setData() is missing selected value(s): ${missing.join(", ")}`);
|
|
772
758
|
}
|
|
759
|
+
if (this.ajaxTimer) {
|
|
760
|
+
clearTimeout(this.ajaxTimer);
|
|
761
|
+
this.ajaxTimer = null;
|
|
762
|
+
}
|
|
763
|
+
this.ajaxController?.abort();
|
|
764
|
+
this.ajaxController = null;
|
|
765
|
+
this.ajaxRequestId += 1;
|
|
766
|
+
this.setLoading(false);
|
|
767
|
+
this.loadingMore = false;
|
|
768
|
+
this.loadError = null;
|
|
769
|
+
this.remoteLoaded = true;
|
|
770
|
+
this.page = 0;
|
|
771
|
+
this.hasMore = false;
|
|
772
|
+
this.nextCursor = void 0;
|
|
773
773
|
this.opts.data = data;
|
|
774
774
|
if (missing.length > 0 && this.opts.missingSelectionPolicy === "prune") {
|
|
775
775
|
this.selected = this.selected.filter((value) => this.optionByValue.has(value));
|
|
@@ -1301,7 +1301,8 @@ var ForgeSelect = class {
|
|
|
1301
1301
|
return { option: existing, created: false };
|
|
1302
1302
|
}
|
|
1303
1303
|
if (this.opts.beforeCreate?.(trimmed) === false) return void 0;
|
|
1304
|
-
|
|
1304
|
+
if (!this.opts.createOption) return this.addCreatedOption({ value: trimmed, label: trimmed });
|
|
1305
|
+
const created = this.opts.createOption(trimmed);
|
|
1305
1306
|
if (created instanceof Promise) {
|
|
1306
1307
|
return created.then((option) => option ? this.addCreatedOption(option) : void 0);
|
|
1307
1308
|
}
|
|
@@ -1981,7 +1982,7 @@ var ForgeSelect = class {
|
|
|
1981
1982
|
this.emitter.emit("loading", loading);
|
|
1982
1983
|
}
|
|
1983
1984
|
remoteCacheKey(query, page, cursor) {
|
|
1984
|
-
return `${query}\0${cursor
|
|
1985
|
+
return `${query}\0${cursor !== void 0 ? `c:${cursor}` : `p:${page}`}`;
|
|
1985
1986
|
}
|
|
1986
1987
|
fetchRemoteResult(query, page, signal, cursor) {
|
|
1987
1988
|
const key = this.remoteCacheKey(query, page, cursor);
|
|
@@ -2089,6 +2090,7 @@ var ForgeSelect = class {
|
|
|
2089
2090
|
if (!append) {
|
|
2090
2091
|
this.data = [];
|
|
2091
2092
|
this.clearRowCaches();
|
|
2093
|
+
this.rebuildOptionIndexes();
|
|
2092
2094
|
}
|
|
2093
2095
|
this.hasMore = false;
|
|
2094
2096
|
this.loadError = error;
|