Merge pull request 'SEV-392: combobox setOptions() for reactive parent-fed option lists' (#5) from sev-392/combobox-setoptions into main

This commit was merged in pull request #5.
This commit is contained in:
2026-06-10 19:09:15 -04:00
2 changed files with 23 additions and 1 deletions
+13 -1
View File
@@ -53,6 +53,7 @@ export function comboboxData(config = {}) {
isOpen: false, isOpen: false,
highlighted: -1, highlighted: -1,
placeholder: config.placeholder || '', placeholder: config.placeholder || '',
_opts: null, // set reactively via setOptions(); see _options getter
init() { init() {
this.syncQueryFromValue(); this.syncQueryFromValue();
@@ -66,8 +67,19 @@ export function comboboxData(config = {}) {
} }
}, },
// setOptions lets a parent feed reactive option lists in via x-effect —
// e.g. x-effect="setOptions(vpicMakes)" — which is the reliable way to
// pass a parent component's reactive array into this nested x-data (a
// plain closure over the parent scope would NOT track updates). Falls back
// to config.options when never called (static lists).
setOptions(raw) {
this._opts = normalizeOptions(raw);
// a shrinking list shouldn't leave a stale highlight selected
if (this.highlighted >= this._opts.length) this.highlighted = -1;
},
get _options() { get _options() {
return normalizeOptions(config.options); return this._opts != null ? this._opts : normalizeOptions(config.options);
}, },
syncQueryFromValue() { syncQueryFromValue() {
+10
View File
@@ -54,3 +54,13 @@ test('empty query lists all options (capped) (SEV-392)', () => {
c.query = ''; c.query = '';
assert.equal(c.filtered.length, 3); assert.equal(c.filtered.length, 3);
}); });
test('setOptions feeds reactive option lists (SEV-392)', () => {
const c = comboboxData({ allowFree: true });
c.setOptions([]); // async source not loaded yet
assert.equal(c.filtered.length, 0);
c.setOptions(['BMW', 'Tesla']); // makes arrive
assert.equal(c.filtered.length, 2);
c.query = 'tes';
assert.deepEqual(c.filtered.map((o) => o.value), ['Tesla']);
});