Skip to content

Commit

Permalink
fix(sbb-select): handle 'multiple' prop change
Browse files Browse the repository at this point in the history
  • Loading branch information
DavideMininni-Fincons committed Jan 7, 2025
1 parent ec5bdfe commit 7bc876e
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 2 deletions.
4 changes: 3 additions & 1 deletion src/elements/accordion/accordion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ class SbbAccordionElement extends SbbHydrationMixin(LitElement) {

/** Whether more than one sbb-expansion-panel can be open at the same time. */
@forceType()
@handleDistinctChange((e, newValue, oldValue) => e._resetExpansionPanels(newValue, !!oldValue))
@handleDistinctChange((e: SbbAccordionElement, newValue, oldValue) =>
e._resetExpansionPanels(newValue, !!oldValue),
)
@property({ type: Boolean })
public accessor multi: boolean = false;

Expand Down
29 changes: 29 additions & 0 deletions src/elements/select/select.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,35 @@ describe(`sbb-select`, () => {
expect(comboBoxElement).to.have.attribute('aria-expanded', 'true');
});

it('update multiple attribute', async () => {
const didOpen = new EventSpy(SbbSelectElement.events.didOpen, element);
element.dispatchEvent(new CustomEvent('click'));

await didOpen.calledOnce();
expect(didOpen.count).to.be.equal(1);
await waitForLitRender(element);

firstOption.dispatchEvent(new CustomEvent('click'));
await waitForLitRender(element);

expect(element.value).to.be.eql('1');

element.toggleAttribute('multiple', true);
await waitForLitRender(element);

expect(element.value).to.be.eql(['1']);

firstOption.dispatchEvent(new CustomEvent('click'));
thirdOption.dispatchEvent(new CustomEvent('click'));
secondOption.dispatchEvent(new CustomEvent('click'));
await waitForLitRender(element);

expect(element.value).to.be.eql(['3', '2']);
element.removeAttribute('multiple');
await waitForLitRender(element);
expect(element.value).to.be.eql('3');
});

it('handles keypress on host', async () => {
const didOpen = new EventSpy(SbbSelectElement.events.didOpen, element);
const didClose = new EventSpy(SbbSelectElement.events.didClose, element);
Expand Down
21 changes: 20 additions & 1 deletion src/elements/select/select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { until } from 'lit/directives/until.js';
import { getNextElementIndex } from '../core/a11y.js';
import { SbbOpenCloseBaseElement } from '../core/base-elements.js';
import { SbbLanguageController } from '../core/controllers.js';
import { forceType, hostAttributes } from '../core/decorators.js';
import { forceType, handleDistinctChange, hostAttributes } from '../core/decorators.js';
import { isNextjs, isSafari, isZeroAnimationDuration, setOrRemoveAttribute } from '../core/dom.js';
import { EventEmitter } from '../core/eventing.js';
import {
Expand Down Expand Up @@ -92,6 +92,7 @@ class SbbSelectElement extends SbbUpdateSchedulerMixin(

/** Whether the select allows for multiple selection. */
@forceType()
@handleDistinctChange((e: SbbSelectElement, newValue: boolean) => e._onMultipleChanged(newValue))
@property({ reflect: true, type: Boolean })
public accessor multiple: boolean = false;

Expand Down Expand Up @@ -305,6 +306,20 @@ class SbbSelectElement extends SbbUpdateSchedulerMixin(
}
}

/**
* If `multiple` changes, the `value` property should be adapted too:
* if the updated value is false, the first available option is set.
*/
private _onMultipleChanged(newValue: boolean): void {
if (this.value !== null) {
if (newValue) {
this.value = [this.value as string];
} else {
this.value = (this.value as string[])[0]!;
}
}
}

/** Sets the _displayValue by checking the internal sbb-options and setting the correct `selected` value on them. */
private _onValueChanged(newValue: string | string[]): void {
const options = this._filteredOptions;
Expand Down Expand Up @@ -453,6 +468,10 @@ class SbbSelectElement extends SbbUpdateSchedulerMixin(
element.toggleAttribute('data-negative', this.negative);
element.toggleAttribute('data-multiple', this.multiple);
});

this.querySelectorAll?.<SbbOptionElement | SbbOptGroupElement>(
'sbb-option, sbb-optgroup',
).forEach((e) => e.requestUpdate?.());
}

private _setupSelect(): void {
Expand Down

0 comments on commit 7bc876e

Please sign in to comment.