Skip to content

Commit

Permalink
Merge branch 'master' into issue1348
Browse files Browse the repository at this point in the history
  • Loading branch information
Donisius committed Jun 22, 2020
2 parents 3772214 + 7699aaf commit f3e3faf
Show file tree
Hide file tree
Showing 11 changed files with 223 additions and 40 deletions.
6 changes: 2 additions & 4 deletions src/combobox/combobox.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,17 +131,15 @@ describe("Combo box", () => {
expect(element.componentInstance.open).toBe(false);
});

it("should call onSearch on keyup event", () => {
const keyupT = new KeyboardEvent("keyup", { "key": "t" });

it("should call onSearch on input event", () => {
fixture = TestBed.createComponent(ComboboxTest);
wrapper = fixture.componentInstance;
fixture.detectChanges();
element = fixture.debugElement.query(By.css("ibm-combo-box"));
spyOn(element.componentInstance, "onSearch");

const textInput = element.nativeElement.querySelector(".bx--text-input");
textInput.dispatchEvent(keyupT);
textInput.dispatchEvent(new Event("input"));
fixture.detectChanges();

expect(element.componentInstance.onSearch).toHaveBeenCalled();
Expand Down
25 changes: 11 additions & 14 deletions src/combobox/combobox.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ import { Observable } from "rxjs";
'bx--multi-select': type === 'multi',
'bx--combo-box': type === 'single' || !pills.length,
'bx--list-box--expanded': open,
'bx--list-box--sm': size === 'sm',
'bx--list-box--xl': size === 'xl',
'bx--list-box--disabled': disabled
}"
class="bx--combo-box bx--list-box"
Expand Down Expand Up @@ -93,10 +95,11 @@ import { Observable } from "rxjs";
<input
#input
[disabled]="disabled"
(keyup)="onSearch($event.target.value)"
(input)="onSearch($event.target.value)"
(keydown.enter)="onSubmit($event)"
[value]="selectedValue"
class="bx--text-input"
[ngClass]="{'bx--text-input--empty': !showClearButton}"
role="searchbox"
tabindex="0"
[attr.aria-aria-labelledby]="id"
Expand Down Expand Up @@ -369,7 +372,7 @@ export class ComboBox implements OnChanges, AfterViewInit, AfterContentInit {
this.view.items = changes.items.currentValue;
// If new items are added into the combobox while there is search input,
// repeat the search.
this.onSearch(this.input.nativeElement.value);
this.onSearch(this.input.nativeElement.value, false);
this.updateSelected();
}
}
Expand Down Expand Up @@ -535,13 +538,11 @@ export class ComboBox implements OnChanges, AfterViewInit, AfterContentInit {
/**
* Sets the list group filter, and manages single select item selection.
*/
public onSearch(searchString) {
this.search.emit(searchString);
if (searchString && this.type === "single") {
this.showClearButton = true;
} else {
this.showClearButton = false;
public onSearch(searchString, shouldEmitSearch = true) {
if (shouldEmitSearch) {
this.search.emit(searchString);
}
this.showClearButton = searchString && this.type === "single";
this.view.filterBy(searchString);
if (searchString !== "") {
this.openDropdown();
Expand All @@ -554,12 +555,7 @@ export class ComboBox implements OnChanges, AfterViewInit, AfterContentInit {
const matches = this.view.getListItems().some(item => item.content.toLowerCase().includes(searchString.toLowerCase()));
if (!matches) {
const selected = this.view.getSelected();
if (selected && selected[0]) {
selected[0].selected = false;
// notify that the selection has changed
this.view.select.emit({ item: selected[0] });
this.propagateChangeCallback(null);
} else {
if (!selected || !selected[0]) {
this.view.filterBy("");
}
}
Expand All @@ -586,6 +582,7 @@ export class ComboBox implements OnChanges, AfterViewInit, AfterContentInit {

this.clearSelected();
this.selectedValue = "";
this.input.nativeElement.value = "";
this.closeDropdown();

this.showClearButton = false;
Expand Down
59 changes: 56 additions & 3 deletions src/combobox/combobox.stories.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { storiesOf, moduleMetadata } from "@storybook/angular";
import { action } from "@storybook/addon-actions";
import { withKnobs, text, boolean, number } from "@storybook/addon-knobs/angular";
import {
withKnobs,
text,
boolean,
number,
select
} from "@storybook/addon-knobs/angular";

import { ComboBoxModule } from "./combobox.module";
import { ButtonModule } from "../button/button.module";
Expand Down Expand Up @@ -40,7 +46,8 @@ const getOptions = (override = {}) => {
}
],
selected: action("selection changed"),
submit: action("submit")
submit: action("submit"),
size: select("size", ["sm", "md", "xl"], "md")
};

return Object.assign({}, options, override);
Expand Down Expand Up @@ -98,6 +105,7 @@ class DynamicListComboBox implements AfterViewInit {
<form [formGroup]="sampleForm" (ngSubmit)="onSubmit(sampleForm)">
<ibm-combo-box
formControlName="combobox"
[size]="size"
[label]="label"
[helperText]="helperText"
[items]="items">
Expand All @@ -108,6 +116,7 @@ class DynamicListComboBox implements AfterViewInit {
style="margin-top: 40px"
formControlName="multibox"
[label]="label"
[size]="size"
[helperText]="helperText"
type="multi"
[items]="items">
Expand All @@ -122,6 +131,7 @@ class ReactiveFormsCombobox implements OnInit {
@Input() items = [];
@Input() label = "";
@Input() helperText = "";
@Input() size = "md";

constructor(private fb: FormBuilder) {}

Expand All @@ -141,10 +151,40 @@ class ReactiveFormsCombobox implements OnInit {
}
}

@Component({
selector: "app-mock-query-search",
template: `
<ibm-combo-box
appendInline="true"
[items]="filterItems"
(search)="onSearch($event)">
<ibm-dropdown-list></ibm-dropdown-list>
</ibm-combo-box>
`
})
class MockQueryCombobox {
filterItems = [];

onSearch() {
setTimeout(() => {
this.filterItems = [
{ content: `Random ${Math.random()}` },
{ content: `Random ${Math.random()}` },
{ content: `Random ${Math.random()}` },
{ content: `Random ${Math.random()}` }
];
}, 1000);
}
}

storiesOf("Components|Combobox", module)
.addDecorator(
moduleMetadata({
declarations: [DynamicListComboBox, ReactiveFormsCombobox],
declarations: [
DynamicListComboBox,
ReactiveFormsCombobox,
MockQueryCombobox
],
imports: [
ComboBoxModule,
ButtonModule,
Expand All @@ -159,6 +199,7 @@ storiesOf("Components|Combobox", module)
<ibm-combo-box
[disabled]="disabled"
[invalid]="invalid"
[size]="size"
[invalidText]="invalidText"
[label]="label"
[helperText]="helperText"
Expand All @@ -180,6 +221,7 @@ storiesOf("Components|Combobox", module)
<ibm-combo-box
[disabled]="disabled"
[invalid]="invalid"
[size]="size"
[invalidText]="invalidText"
[label]="label"
[helperText]="helperText"
Expand All @@ -200,6 +242,7 @@ storiesOf("Components|Combobox", module)
<ibm-combo-box
[disabled]="disabled"
[invalid]="invalid"
[size]="size"
[invalidText]="invalidText"
[label]="label"
[helperText]="helperText"
Expand Down Expand Up @@ -252,6 +295,7 @@ storiesOf("Components|Combobox", module)
[invalid]="invalid"
[invalidText]="invalidText"
[label]="label"
[size]="size"
[helperText]="helperText"
[items]="items"
(selected)="onSelected()"
Expand Down Expand Up @@ -286,6 +330,7 @@ storiesOf("Components|Combobox", module)
[invalid]="invalid"
[invalidText]="invalidText"
[label]="label"
[size]="size"
[helperText]="helperText"
[items]="items"
type="multi"
Expand All @@ -300,6 +345,7 @@ storiesOf("Components|Combobox", module)
template: `
<app-reactive-combobox
[items]="items"
[size]="size"
[label]="label"
[helperText]="helperText">
</app-reactive-combobox>
Expand All @@ -314,6 +360,7 @@ storiesOf("Components|Combobox", module)
[label]="label"
[helperText]="helperText"
[items]="items"
[size]="size"
type="multi"
(selected)="selected($event)"
(submit)="submit($event)">
Expand All @@ -339,6 +386,7 @@ storiesOf("Components|Combobox", module)
[invalid]="invalid"
[invalidText]="invalidText"
[label]="label"
[size]="size"
[helperText]="helperText"
[items]="items"
[(ngModel)]="model"
Expand All @@ -353,6 +401,11 @@ storiesOf("Components|Combobox", module)
model: { "content": "three", "selected": true }
})
}))
.add("Mock query search", () => ({
template: `
<app-mock-query-search></app-mock-query-search>
`
}))
.add("Documentation", () => ({
template: `
<ibm-documentation src="documentation/components/ComboBox.html"></ibm-documentation>
Expand Down
4 changes: 3 additions & 1 deletion src/datepicker/datepicker.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { DatePickerInput } from "../datepicker-input/datepicker-input.component"
import { CalendarModule } from "@carbon/icons-angular";
import { FormsModule } from "@angular/forms";
import { UtilsModule } from "../utils/utils.module";
import { I18nModule } from "../i18n";

@Component({
template: `
Expand Down Expand Up @@ -41,7 +42,8 @@ describe("DatePicker", () => {
imports: [
CalendarModule,
UtilsModule,
FormsModule
FormsModule,
I18nModule
]
});
});
Expand Down
59 changes: 47 additions & 12 deletions src/datepicker/datepicker.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import {
AfterViewChecked,
AfterViewInit,
ViewChild,
AfterContentInit
AfterContentInit,
OnInit,
SimpleChange
} from "@angular/core";
import rangePlugin from "flatpickr/dist/plugins/rangePlugin";
import flatpickr from "flatpickr";
Expand All @@ -23,6 +25,7 @@ import { Subscription } from "rxjs";
import * as languages from "flatpickr/dist/l10n/index";
import { DatePickerInput } from "../datepicker-input/datepicker-input.component";
import { ElementService } from "../utils/element.service";
import { I18n } from "./../i18n";

/**
* [See demo](../../?path=/story/date-picker--single)
Expand Down Expand Up @@ -93,7 +96,13 @@ import { ElementService } from "../utils/element.service";
],
encapsulation: ViewEncapsulation.None
})
export class DatePicker implements OnDestroy, OnChanges, AfterViewChecked, AfterViewInit, AfterContentInit {
export class DatePicker implements
OnInit,
OnDestroy,
OnChanges,
AfterViewChecked,
AfterViewInit,
AfterContentInit {
private static datePickerCount = 0;

/**
Expand Down Expand Up @@ -215,18 +224,25 @@ export class DatePicker implements OnDestroy, OnChanges, AfterViewChecked, After

protected visibilitySubscription = new Subscription();

constructor(protected elementRef: ElementRef, protected elementService: ElementService) { }
constructor(
protected elementRef: ElementRef,
protected elementService: ElementService,
protected i18n: I18n
) { }

ngOnInit() {
// if i18n is set to anything other than en we'll want to change the language
// otherwise we'll just use the local setting
if (this.i18n.getLocale() !== "en") {
this.i18n.getLocaleObservable().subscribe(locale => {
this.language = locale;
this.resetFlackpickrInstance();
});
}
}

ngOnChanges(changes: SimpleChanges) {
if (this.isFlatpickrLoaded()) {
let dates = this.flatpickrInstance.selectedDates;
if (changes.value && this.didDateValueChange(changes.value.currentValue, changes.value.previousValue)) {
dates = changes.value.currentValue;
}
// only reset the flatpickr instance on Input changes
this.flatpickrInstance = flatpickr(`#${this.id}`, this.flatpickrOptions);
this.setDateValues(dates);
}
this.resetFlackpickrInstance(changes.value);
}

ngAfterViewInit() {
Expand Down Expand Up @@ -373,6 +389,25 @@ export class DatePicker implements OnDestroy, OnChanges, AfterViewChecked, After
});
}

/**
* Resets the flatpickr instance while keeping the date values (or updating them if newDates is provided)
*
* Used to pick up input changes or locale changes.
*
* @param newDates An optional SimpleChange of date values
*/
protected resetFlackpickrInstance(newDates?: SimpleChange) {
if (this.isFlatpickrLoaded()) {
let dates = this.flatpickrInstance.selectedDates;
if (newDates && this.didDateValueChange(newDates.currentValue, newDates.previousValue)) {
dates = newDates.currentValue;
}
// only reset the flatpickr instance on Input changes
this.flatpickrInstance = flatpickr(`#${this.id}`, this.flatpickrOptions);
this.setDateValues(dates);
}
}

/**
* Carbon uses a number of specific classnames for parts of the flatpickr - this idempotent method applies them if needed.
*/
Expand Down
4 changes: 3 additions & 1 deletion src/datepicker/datepicker.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { NgModule } from "@angular/core";
import { CommonModule } from "@angular/common";
import { DatePicker } from "./datepicker.component";
import { UtilsModule } from "../utils/utils.module";
import { I18nModule } from "./../i18n";

@NgModule({
declarations: [
Expand All @@ -15,7 +16,8 @@ import { UtilsModule } from "../utils/utils.module";
imports: [
CommonModule,
DatePickerInputModule,
UtilsModule
UtilsModule,
I18nModule
]
})
export class DatePickerModule { }
Loading

0 comments on commit f3e3faf

Please sign in to comment.