Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
fix(combobox): Fixes an issue where an exception was thrown when load…
Browse files Browse the repository at this point in the history
…ing was true initially.
  • Loading branch information
ffriedl89 authored and nimrod13 committed Dec 15, 2020
1 parent 1f095f8 commit 4bf5d50
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 56 deletions.
133 changes: 83 additions & 50 deletions libs/barista-components/experimental/combobox/src/combobox.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ describe('Combobox', () => {
HttpClientTestingModule,
DtIconModule.forRoot({ svgIconLocation: `{{name}}.svg` }),
],
declarations: [TestComponent],
declarations: [TestComponent, TestLoadingComponent],
providers: [
//{ provide: NgZone, useFactory: () => (zone = new MockNgZone()) },
],
Expand All @@ -76,65 +76,79 @@ describe('Combobox', () => {
overlayContainerElement = oc.getContainerElement();
}));

beforeEach(() => {
fixture = createComponent(TestComponent);
combobox = fixture.debugElement.query(By.directive(DtCombobox))
.componentInstance;
input = fixture.debugElement.query(By.css('.dt-combobox-input'))
.nativeElement;
trigger = fixture.debugElement.query(By.css('.dt-combobox-trigger'))
.nativeElement;
});

afterEach(() => {
overlayContainer.ngOnDestroy();
(overlayContainer as any) = null;
(overlayContainerElement as any) = null;
});

it('should not open when the options are empty', fakeAsync(() => {
focusInput(input);
expect(trigger.classList.contains('dt-combobox-open')).toBeFalsy();
expect(
overlayContainerElement.querySelectorAll('dt-option').length,
).toEqual(0);
}));

it('should return true when options is an empty array', () => {
expect(combobox.empty).toBeTruthy();
});

it('should emit an event when the panel is opened', fakeAsync(() => {
// fixture.componentInstance.setOptions();
// fixture.detectChanges();
// focusInput(input);
// expect(fixture.componentInstance.openedSpy).toHaveBeenCalled();
}));
describe('Basic', () => {
beforeEach(() => {
fixture = createComponent(TestComponent);
combobox = fixture.debugElement.query(By.directive(DtCombobox))
.componentInstance;
input = fixture.debugElement.query(By.css('.dt-combobox-input'))
.nativeElement;
trigger = fixture.debugElement.query(By.css('.dt-combobox-trigger'))
.nativeElement;
});

it('should show options after setting them from a previously empty set of options', fakeAsync(() => {
fixture.componentInstance.setOptions();
fixture.detectChanges();
focusInput(input);
it('should not open when the options are empty', fakeAsync(() => {
focusInput(input);
expect(trigger.classList.contains('dt-combobox-open')).toBeFalsy();
expect(
overlayContainerElement.querySelectorAll('dt-option').length,
).toEqual(0);
}));

expect(trigger.classList.contains('dt-combobox-open')).toBeTruthy();
expect(
overlayContainerElement.querySelectorAll('dt-option').length,
).toEqual(3);
}));
it('should return true when options is an empty array', () => {
expect(combobox.empty).toBeTruthy();
});

it('should set the value in the input correctly if a value is set at runtime', fakeAsync(() => {
fixture.componentInstance.setOptions();
fixture.detectChanges();
expect(input.value).toBe('');
expect(input.placeholder).toBe('My placeholder');
it('should emit an event when the panel is opened', fakeAsync(() => {
// fixture.componentInstance.setOptions();
// fixture.detectChanges();
// focusInput(input);
// expect(fixture.componentInstance.openedSpy).toHaveBeenCalled();
}));

it('should show options after setting them from a previously empty set of options', fakeAsync(() => {
fixture.componentInstance.setOptions();
fixture.detectChanges();
focusInput(input);

expect(trigger.classList.contains('dt-combobox-open')).toBeTruthy();
expect(
overlayContainerElement.querySelectorAll('dt-option').length,
).toEqual(3);
}));

it('should set the value in the input correctly if a value is set at runtime', fakeAsync(() => {
fixture.componentInstance.setOptions();
fixture.detectChanges();
expect(input.value).toBe('');
expect(input.placeholder).toBe('My placeholder');

fixture.componentInstance.value$.next({
name: 'Value 2',
value: '[value: Value 2]',
});
fixture.detectChanges();
expect(input.value).toBe('Value 2');
}));
});

fixture.componentInstance.value$.next({
name: 'Value 2',
value: '[value: Value 2]',
});
fixture.detectChanges();
expect(input.value).toBe('Value 2');
}));
it('should not throw an error when loading is true initially', () => {
let loadingFixture;
try {
loadingFixture = createComponent(TestLoadingComponent);
} catch (e) {
expect(e.message).toBeTruthy();
} finally {
expect.assertions(0);
loadingFixture.destroy();
}
});
});

/** Test component */
Expand Down Expand Up @@ -181,3 +195,22 @@ class TestComponent {
];
}
}

@Component({
selector: 'dt-test',
template: `
<dt-combobox [loading]="loading">
<dt-option *ngFor="let option of options" [value]="option">
{{ option.name }}
</dt-option>
</dt-combobox>
`,
})
class TestLoadingComponent {
options: { name: string; value: string }[] = [
{ name: 'Value 1', value: '[value: Value 1]' },
{ name: 'Value 2', value: '[value: Value 2]' },
{ name: 'Value 3', value: '[value: Value 3]' },
];
loading = true;
}
19 changes: 13 additions & 6 deletions libs/barista-components/experimental/combobox/src/combobox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ export class DtCombobox<T>
*/
@ViewChild('autocompleteContent') _templatePortalContent: TemplateRef<any>;
/** @internal The autocomplete instance that holds all options */
@ViewChild(DtAutocomplete) _autocomplete: DtAutocomplete<T>;
@ViewChild(DtAutocomplete, { static: true }) _autocomplete: DtAutocomplete<T>;

/** @internal The options received via ng-content */
@ContentChildren(DtOption, { descendants: true })
Expand Down Expand Up @@ -332,6 +332,10 @@ export class DtCombobox<T>
.subscribe(() => {
this._resetInputValue();
});

this._autocomplete.opened.pipe(takeUntil(this._destroy)).subscribe(() => {
this._closeOtherComboboxInstances();
});
}

ngAfterContentInit(): void {
Expand Down Expand Up @@ -431,24 +435,27 @@ export class DtCombobox<T>
this._changeDetectorRef.markForCheck();
}

private _closeOtherComboboxInstances(): void {
if (currentlyOpenCombobox && currentlyOpenCombobox !== this) {
currentlyOpenCombobox._autocompleteTrigger.closePanel();
}
currentlyOpenCombobox = this;
}

/**
* Opens the autocomplete panel and makes sure that all
* other combobox panels are closed correctly.
*/
private _openPanel(): void {
if (currentlyOpenCombobox && currentlyOpenCombobox !== this) {
currentlyOpenCombobox._autocompleteTrigger.closePanel();
}
this._autocompleteTrigger.openPanel();
currentlyOpenCombobox = this;
}

/**
* Closes the autocomplete panel and makes sure handles
* the global autocomplete panel case correctly.
*/
private _closePanel(): void {
this._autocompleteTrigger.openPanel();
this._autocompleteTrigger.closePanel();
currentlyOpenCombobox = null;
}

Expand Down

0 comments on commit 4bf5d50

Please sign in to comment.