From 6881d316509d92616511c93f381bbb6e2c65ff44 Mon Sep 17 00:00:00 2001 From: Bastian de Byl Date: Wed, 10 Jun 2026 20:20:59 -0400 Subject: [PATCH] SEV-408: combobox displayValue option (show code, search by label) v0.5.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When displayValue:true, the input shows the selected option's value (e.g. a state code "TX") while the dropdown stays label-searchable ("Texas") — for a field searched by name but displayed compactly. Backward-compatible (default false). 20/20 tests pass. Co-Authored-By: Claude Fable 5 --- package.json | 2 +- src/combobox.js | 9 +++++++-- src/combobox.test.js | 27 +++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index c5905a0..871468a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@switchev/web-shared", - "version": "0.4.0", + "version": "0.5.0", "description": "Shared browser helpers (formatters, markdown, image polling, combobox) for the SwitchEV frontends", "type": "module", "exports": { diff --git a/src/combobox.js b/src/combobox.js index 6efe67a..3ab347d 100644 --- a/src/combobox.js +++ b/src/combobox.js @@ -46,6 +46,10 @@ export function comboboxData(config = {}) { const allowFree = config.allowFree !== false; const fuzzy = config.fuzzy !== false; const limit = config.limit || 50; + // displayValue: after selecting, show the option's VALUE (e.g. a state code + // "TX") in the input instead of its LABEL ("Texas"), while the dropdown stays + // label-searchable. Lets a field be searched by name but display the code. + const displayValue = config.displayValue === true; return { value: config.value ?? '', @@ -89,7 +93,8 @@ export function comboboxData(config = {}) { return; } const match = this._options.find((o) => o.value === String(v)); - this.query = match ? match.label : allowFree ? String(v) : ''; + if (match) this.query = displayValue ? match.value : match.label; + else this.query = allowFree ? String(v) : ''; }, get filtered() { @@ -121,7 +126,7 @@ export function comboboxData(config = {}) { choose(opt) { this.value = opt.value; - this.query = opt.label; + this.query = displayValue ? opt.value : opt.label; this.close(); }, diff --git a/src/combobox.test.js b/src/combobox.test.js index 9571557..a4e8010 100644 --- a/src/combobox.test.js +++ b/src/combobox.test.js @@ -64,3 +64,30 @@ test('setOptions feeds reactive option lists (SEV-392)', () => { c.query = 'tes'; assert.deepEqual(c.filtered.map((o) => o.value), ['Tesla']); }); + +test('displayValue shows the code in the input, searches by label (SEV-408)', () => { + const c = comboboxData({ + options: [{ value: 'CA', label: 'California' }, { value: 'TX', label: 'Texas' }], + allowFree: false, + displayValue: true, + }); + c.init(); + // search by name + c.query = 'tex'; + assert.deepEqual(c.filtered.map((o) => o.value), ['TX']); + // choosing shows the CODE, not the name + c.choose({ value: 'TX', label: 'Texas' }); + assert.equal(c.value, 'TX'); + assert.equal(c.query, 'TX'); +}); + +test('displayValue syncs the code from an external value (SEV-408)', () => { + const c = comboboxData({ + options: [{ value: 'OR', label: 'Oregon' }], + allowFree: false, + displayValue: true, + value: 'OR', + }); + c.init(); + assert.equal(c.query, 'OR'); // shows code, not "Oregon" +}); -- 2.52.0