diff --git a/packages/cfpb-design-system/src/elements/cfpb-select/index.js b/packages/cfpb-design-system/src/elements/cfpb-select/index.js index 09c5594685..22d7281cea 100644 --- a/packages/cfpb-design-system/src/elements/cfpb-select/index.js +++ b/packages/cfpb-design-system/src/elements/cfpb-select/index.js @@ -218,9 +218,26 @@ export class CfpbSelect extends LitElement { }); } + willUpdate(changedProps) { + if (changedProps.has('multiple')) { + const previousMultiple = changedProps.get('multiple'); + + if (previousMultiple && !this.multiple) { + this.#normalizeSingleSelection(); + } + } + } + updated(changedProps) { if (changedProps.has('multiple')) { + const previousMultiple = changedProps.get('multiple'); + this.#eventProxy = this.#createEventProxy(); + + if (previousMultiple && !this.multiple && this.#displayLabel.value) { + this.#displayLabel.value.textContent = + this.optionList.find((item) => item.checked)?.value ?? ''; + } } if (changedProps.has('isExpanded')) { @@ -244,6 +261,21 @@ export class CfpbSelect extends LitElement { } } + #normalizeSingleSelection() { + const selectedValues = + this.#list.value?.checkedItems?.map((item) => item.value) ?? + this.optionList + .filter((item) => item.checked) + .map((item) => item.value); + + const selectedValue = selectedValues.at(-1) ?? ''; + + this.optionList = this.optionList.map((item) => ({ + ...item, + checked: item.value === selectedValue, + })); + } + #createEventProxy() { const common = { list: this.#list.value, diff --git a/packages/cfpb-design-system/src/elements/cfpb-select/index.spec.js b/packages/cfpb-design-system/src/elements/cfpb-select/index.spec.js new file mode 100644 index 0000000000..9c3d12884b --- /dev/null +++ b/packages/cfpb-design-system/src/elements/cfpb-select/index.spec.js @@ -0,0 +1,37 @@ +import { CfpbSelect } from './index'; + +beforeAll(() => { + CfpbSelect.init(); +}); + +describe(' tests', () => { + afterEach(() => { + document.body.innerHTML = ''; + }); + + it('keeps only the last selected option when switching to single mode', async () => { + const select = document.createElement('cfpb-select'); + + select.multiple = true; + select.optionList = [ + { value: 'Alpha', checked: true }, + { value: 'Bravo', checked: true }, + { value: 'Charlie', checked: false }, + ]; + + document.body.appendChild(select); + await select.updateComplete; + + select.multiple = false; + await select.updateComplete; + + const checkedValues = select.optionList + .filter((item) => item.checked) + .map((item) => item.value); + + expect(checkedValues).toEqual(['Bravo']); + expect(select.shadowRoot.querySelector('.o-select__label').textContent).toBe( + 'Bravo', + ); + }); +});