diff --git a/packages/components/select/select.component.spec.ts b/packages/components/select/select.component.spec.ts
index 3a0de65b8..82ca69ba3 100644
--- a/packages/components/select/select.component.spec.ts
+++ b/packages/components/select/select.component.spec.ts
@@ -1943,6 +1943,30 @@ class VirtualSelectWithScrolledToBottom {
}
}
+@Component({
+ selector: 'multi-select-with-cleaner',
+ imports: [KbqSelectModule, ReactiveFormsModule],
+ template: `
+
+
+ @for (food of foods; track food) {
+ {{ food.viewValue }}
+ }
+
+
+
+ `
+})
+class MultiSelectWithCleaner {
+ foods = [
+ { value: 'steak-0', viewValue: 'Steak' },
+ { value: 'pizza-1', viewValue: 'Pizza' },
+ { value: 'tacos-2', viewValue: 'Tacos' }
+ ];
+ control = new UntypedFormControl(['steak-0', 'pizza-1']);
+ readonly select = viewChild.required(KbqSelect);
+}
+
describe('KbqSelect', () => {
let overlayContainer: OverlayContainer;
let overlayContainerElement: HTMLElement;
@@ -1996,6 +2020,7 @@ describe('KbqSelect', () => {
BasicSelect,
BasicEvents,
MultiSelect,
+ MultiSelectWithCleaner,
SelectWithGroups,
SelectWithGroupsAndNgContainer,
SelectWithFormFieldLabel,
@@ -3283,6 +3308,74 @@ describe('KbqSelect', () => {
expect(value.nativeElement.textContent).toContain('Food');
}));
+
+ it('should update FormControl value to null after clear on single select', fakeAsync(() => {
+ fixture.componentInstance.control = new UntypedFormControl('pizza-1');
+ fixture.detectChanges();
+ flush();
+
+ expect(fixture.componentInstance.control.value).toBe('pizza-1');
+
+ cleaner = fixture.debugElement.query(By.css('.kbq-select__cleaner')).nativeElement;
+ cleaner.click();
+ fixture.detectChanges();
+ flush();
+
+ expect(fixture.componentInstance.control.value).toBeUndefined();
+ }));
+ });
+
+ describe('Clear value — multiple select', () => {
+ let multiFixture: ComponentFixture;
+
+ beforeEach(fakeAsync(() => {
+ multiFixture = TestBed.createComponent(MultiSelectWithCleaner);
+ multiFixture.detectChanges();
+ flush();
+ multiFixture.detectChanges();
+ }));
+
+ it('should update FormControl value to empty array after clear', fakeAsync(() => {
+ expect(multiFixture.componentInstance.control.value).toEqual(['steak-0', 'pizza-1']);
+
+ const multiCleaner = multiFixture.debugElement.query(By.css('.kbq-select__cleaner')).nativeElement;
+
+ multiCleaner.click();
+ multiFixture.detectChanges();
+ flush();
+
+ expect(multiFixture.componentInstance.control.value).toEqual([]);
+ }));
+
+ it('should deselect all options visually after clear', fakeAsync(() => {
+ multiFixture.componentInstance.select().open();
+ multiFixture.detectChanges();
+ flush();
+
+ const optionsBefore = Array.from(
+ overlayContainerElement.querySelectorAll('kbq-option')
+ ) as HTMLElement[];
+
+ expect(optionsBefore.filter((o) => o.classList.contains('kbq-selected')).length).toBe(2);
+
+ multiFixture.componentInstance.select().close();
+ multiFixture.detectChanges();
+ flush();
+
+ multiFixture.debugElement.query(By.css('.kbq-select__cleaner')).nativeElement.click();
+ multiFixture.detectChanges();
+ flush();
+
+ multiFixture.componentInstance.select().open();
+ multiFixture.detectChanges();
+ flush();
+
+ const optionsAfter = Array.from(
+ overlayContainerElement.querySelectorAll('kbq-option')
+ ) as HTMLElement[];
+
+ expect(optionsAfter.filter((o) => o.classList.contains('kbq-selected')).length).toBe(0);
+ }));
});
describe('keyboard scrolling', () => {
diff --git a/packages/components/select/select.component.ts b/packages/components/select/select.component.ts
index d763f9ffa..fb483d6c4 100644
--- a/packages/components/select/select.component.ts
+++ b/packages/components/select/select.component.ts
@@ -989,7 +989,7 @@ export class KbqSelect
// need to prevent scrolling
$event.preventDefault();
- this.selectionModel.clear(false);
+ this.selectionModel.clear();
this.keyManager.setActiveItem(-1);
this.propagateChanges();