Skip to content

Commit

Permalink
Merge branch '6.2.x' into rkolev/fix-2971-6.2.x
Browse files Browse the repository at this point in the history
  • Loading branch information
ddincheva authored Nov 19, 2018
2 parents 802d272 + 41f3eb1 commit 4f9f845
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 85 deletions.
100 changes: 50 additions & 50 deletions projects/igniteui-angular/src/lib/combo/combo.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,58 +14,58 @@
{{ item[key] }}
</ng-template>

<div class="igx-combo" [style.width]="width" role="combobox" [attr.aria-expanded]="!dropdown.collapsed" aria-haspopup="listbox" [attr.aria-owns]="dropdown.id">
<igx-input-group [type]="type" (click)="onInputClick($event)">
<input igxInput #comboInput name="comboInput" type="text" [(ngModel)]="value" readonly [placeholder]="placeholder" [disabled]="disabled" (blur)="onBlur($event)"/>
<igx-suffix *ngIf="value.length" class="clearButton" aria-label="Clear Selection" igxRipple (click)="handleClearItems($event)">
<igx-icon fontSet="material">clear</igx-icon>
</igx-suffix>
<igx-suffix igxButton="icon" class="dropdownToggleButton" igxRipple>
<igx-icon *ngIf="dropdown.collapsed; else toggleUp" fontSet="material">arrow_drop_down</igx-icon>
<ng-template #toggleUp>
<igx-icon fontSet="material">arrow_drop_up</igx-icon>
</ng-template>
</igx-suffix>
<igx-input-group [displayDensity]="displayDensity" [type]="type" (click)="onInputClick($event)">
<input igxInput #comboInput name="comboInput" type="text" [(ngModel)]="value" readonly [placeholder]="placeholder"
[disabled]="disabled" (blur)="onBlur($event)" />
<igx-suffix *ngIf="value.length" class="clearButton" aria-label="Clear Selection" igxRipple (click)="handleClearItems($event)">
<igx-icon fontSet="material">clear</igx-icon>
</igx-suffix>
<igx-suffix igxButton="icon" class="dropdownToggleButton" igxRipple>
<igx-icon *ngIf="dropdown.collapsed; else toggleUp" fontSet="material">arrow_drop_down</igx-icon>
<ng-template #toggleUp>
<igx-icon fontSet="material">arrow_drop_up</igx-icon>
</ng-template>
</igx-suffix>
</igx-input-group>
<igx-combo-drop-down #igxComboDropDown class="igx-combo__drop-down" [width]="itemsWidth || '100%'">
<igx-input-group [displayDensity]="displayDensity" class="igx-combo__search">
<input class="igx-combo-input" igxInput #searchInput name="searchInput" type="text" [(ngModel)]="searchValue"
(ngModelChange)="handleInputChange($event)" (keyup)="handleKeyUp($event)" (keydown)="handleKeyDown($event)"
(focus)="dropdown.onBlur($event)" [placeholder]="searchPlaceholder" aria-autocomplete="both"
[attr.aria-owns]="dropdown.id" [attr.aria-labelledby]="ariaLabelledBy" />
</igx-input-group>
<igx-combo-drop-down #igxComboDropDown class="igx-combo__drop-down" [width]="itemsWidth || '100%'">
<igx-input-group class="igx-combo__search">
<input class="igx-combo-input" igxInput #searchInput name="searchInput" type="text" [(ngModel)]="searchValue" (ngModelChange)="handleInputChange($event)"
(keyup)="handleKeyUp($event)" (keydown)="handleKeyDown($event)" (focus)="dropdown.onBlur($event)" [placeholder]="searchPlaceholder" aria-autocomplete="both"
[attr.aria-owns]="dropdown.id" [attr.aria-labelledby]="ariaLabelledBy" />
</igx-input-group>
<ng-container *ngTemplateOutlet="headerTemplate; context: {$implicit: this}">
</ng-container>
<div #dropdownItemContainer class="igx-combo__content" [style.overflow]="'hidden'" [style.maxHeight.px]="itemsMaxHeight"
[igxDropDownItemNavigation]="dropdown" [tabindex]="dropdown.collapsed ? -1 : 0" role="listbox" [attr.id]="dropdown.id">
<ng-template igxFor let-item [igxForOf]="data | comboFiltering:filteringExpressions:filteringLogic | comboSorting:sortingExpressions | comboGrouping:groupKey"
[igxForScrollOrientation]="'vertical'" [igxForContainerSize]="itemsMaxHeight"
[igxForItemSize]="itemHeight" (onChunkPreload)="dataLoading($event)" #virtualScrollContainer>
<igx-combo-item [value]="item" isHeader={{item.isHeader}} role="option">
<ng-container *ngIf="!item.isHeader">
<igx-checkbox [checked]="isItemSelected(item)" disableRipple="true" disabled="true" class="igx-combo__checkbox"></igx-checkbox>
</ng-container>
<ng-container *ngIf="item.isHeader">
<ng-container *ngTemplateOutlet="headerItemTemplate ? headerItemTemplate : headerItemBase; context: {$implicit: item, data: data, valueKey: valueKey, groupKey: groupKey, displayKey: displayKey}"></ng-container>
</ng-container>
<ng-container *ngIf="!item.isHeader">
<ng-container #listItem *ngTemplateOutlet="template; context: {$implicit: item, data: data, valueKey: valueKey, displayKey: displayKey};"></ng-container>
</ng-container>
</igx-combo-item>
</ng-template>
</div>
<div class="igx-combo__add" *ngIf="filteredData.length === 0 || isAddButtonVisible()">
<div class="igx-combo__empty" *ngIf="filteredData.length === 0">
<ng-container *ngTemplateOutlet="emptyTemplate ? emptyTemplate : empty; context: {$implicit: this}">
<ng-container *ngTemplateOutlet="headerTemplate; context: {$implicit: this}">
</ng-container>
<div #dropdownItemContainer class="igx-combo__content" [style.overflow]="'hidden'" [style.maxHeight.px]="itemsMaxHeight"
[igxDropDownItemNavigation]="dropdown" [tabindex]="dropdown.collapsed ? -1 : 0" role="listbox" [attr.id]="dropdown.id">
<ng-template igxFor let-item [igxForOf]="data | comboFiltering:filteringExpressions:filteringLogic | comboSorting:sortingExpressions | comboGrouping:groupKey"
[igxForScrollOrientation]="'vertical'" [igxForContainerSize]="itemsMaxHeight" [igxForItemSize]="itemHeight"
(onChunkPreload)="dataLoading($event)" #virtualScrollContainer>
<igx-combo-item [value]="item" isHeader={{item.isHeader}} role="option">
<ng-container *ngIf="!item.isHeader">
<igx-checkbox [checked]="isItemSelected(item)" disableRipple="true" disabled="true" class="igx-combo__checkbox"></igx-checkbox>
</ng-container>
<ng-container *ngIf="item.isHeader">
<ng-container *ngTemplateOutlet="headerItemTemplate ? headerItemTemplate : headerItemBase; context: {$implicit: item, data: data, valueKey: valueKey, groupKey: groupKey, displayKey: displayKey}"></ng-container>
</ng-container>
</div>
<igx-combo-item *ngIf="isAddButtonVisible()" [tabindex]="dropdown.collapsed ? -1 : customValueFlag ? 1 : -1" class="igx-combo__add-item"
igxRipple (keypress)="addItemToCollection()" [isHeader]="false" [disabled]="false" [value]="'ADD ITEM'" role="button"
aria-label="Add Item">
<ng-container *ngTemplateOutlet="addItemTemplate ? addItemTemplate : addItemDefault; context: {$implicit: this}">
<ng-container *ngIf="!item.isHeader">
<ng-container #listItem *ngTemplateOutlet="template; context: {$implicit: item, data: data, valueKey: valueKey, displayKey: displayKey};"></ng-container>
</ng-container>
</igx-combo-item>
</ng-template>
</div>
<div class="igx-combo__add" *ngIf="filteredData.length === 0 || isAddButtonVisible()">
<div class="igx-combo__empty" *ngIf="filteredData.length === 0">
<ng-container *ngTemplateOutlet="emptyTemplate ? emptyTemplate : empty; context: {$implicit: this}">
</ng-container>
</div>
<ng-container *ngTemplateOutlet="footerTemplate; context: {$implicit: this}">
</ng-container>
</igx-combo-drop-down>
</div>
<igx-combo-item *ngIf="isAddButtonVisible()" [tabindex]="dropdown.collapsed ? -1 : customValueFlag ? 1 : -1"
class="igx-combo__add-item" igxRipple (keypress)="addItemToCollection()" [isHeader]="false" [disabled]="false"
[value]="'ADD ITEM'" role="button" aria-label="Add Item">
<ng-container *ngTemplateOutlet="addItemTemplate ? addItemTemplate : addItemDefault; context: {$implicit: this}">
</ng-container>
</igx-combo-item>
</div>
<ng-container *ngTemplateOutlet="footerTemplate; context: {$implicit: this}">
</ng-container>
</igx-combo-drop-down>
28 changes: 14 additions & 14 deletions projects/igniteui-angular/src/lib/combo/combo.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1545,18 +1545,16 @@ describe('igxCombo', () => {
expect(comboWrapper.attributes.getNamedItem('ng-reflect-placeholder').nodeValue).toEqual('Items');
expect(comboWrapper.attributes.getNamedItem('ng-reflect-data').nodeValue).toEqual('Item 1,Item 2,Item 3');
expect(comboWrapper.attributes.getNamedItem('ng-reflect-filterable')).toBeTruthy();
expect(comboWrapper.childElementCount).toEqual(1);

const comboElement = comboWrapper.children[0];
expect(comboElement.attributes.getNamedItem('class').nodeValue).toEqual(CSS_CLASS_COMBO);
expect(comboElement.attributes.getNamedItem('role').nodeValue).toEqual('combobox');
expect(comboElement.style.width).toEqual(defaultComboWidth);
expect(comboElement.attributes.getNamedItem('aria-haspopup').nodeValue).toEqual('listbox');
expect(comboElement.attributes.getNamedItem('aria-expanded').nodeValue).toEqual('false');
expect(comboElement.attributes.getNamedItem('aria-owns').nodeValue).toEqual(fix.componentInstance.combo.dropdown.id);
expect(comboElement.childElementCount).toEqual(2);

const inputGroupElement = comboElement.children[0];
expect(comboWrapper.childElementCount).toEqual(2); // Input Group + Dropdown
expect(comboWrapper.attributes.getNamedItem('class').nodeValue).toEqual(CSS_CLASS_COMBO);
expect(comboWrapper.attributes.getNamedItem('role').nodeValue).toEqual('combobox');
expect(comboWrapper.style.width).toEqual(defaultComboWidth);
expect(comboWrapper.attributes.getNamedItem('aria-haspopup').nodeValue).toEqual('listbox');
expect(comboWrapper.attributes.getNamedItem('aria-expanded').nodeValue).toEqual('false');
expect(comboWrapper.attributes.getNamedItem('aria-owns').nodeValue).toEqual(fix.componentInstance.combo.dropdown.id);
expect(comboWrapper.childElementCount).toEqual(2);

const inputGroupElement = comboWrapper.children[0];
expect(inputGroupElement.attributes.getNamedItem('ng-reflect-type').nodeValue).toEqual('box');
expect(inputGroupElement.classList.contains(CSS_CLASS_INPUTGROUP)).toBeTruthy();
expect(inputGroupElement.classList.contains('igx-input-group--box')).toBeTruthy();
Expand Down Expand Up @@ -1590,7 +1588,7 @@ describe('igxCombo', () => {
expect(inputGroupBorder.classList.contains(CSS_CLASS_INPUTGROUP_BORDER)).toBeTruthy();
expect(inputGroupBorder.childElementCount).toEqual(0);

const dropDownElement = comboElement.children[1];
const dropDownElement = comboWrapper.children[1];
expect(dropDownElement.classList.contains(CSS_CLASS_COMBO_DROPDOWN)).toBeTruthy();
expect(dropDownElement.classList.contains(CSS_CLASS_DROPDOWN)).toBeTruthy();
expect(dropDownElement.attributes.getNamedItem('ng-reflect-width').nodeValue).toEqual(defaultComboDDWidth);
Expand Down Expand Up @@ -1837,6 +1835,7 @@ describe('igxCombo', () => {
expect(focusedItem_2.classList.contains(CSS_CLASS_FOCUSED)).toBeTruthy();
expect(focusedItem_1.classList.contains(CSS_CLASS_FOCUSED)).toBeFalsy();
}));

it('Should adjust combo width to the container element width when set to 100%', fakeAsync(() => {
const fixture = TestBed.createComponent(IgxComboInContainerTestComponent);
fixture.detectChanges();
Expand All @@ -1853,7 +1852,7 @@ describe('igxCombo', () => {
combo.toggle();
tick();
fixture.detectChanges();

tick();
const inputElement = fixture.debugElement.query(By.css('.' + CSS_CLASS_INPUTGROUP_WRAPPER)).nativeElement;
const dropDownElement = fixture.debugElement.query(By.css('.' + CSS_CLASS_DROPDOWNLIST)).nativeElement;
containerElementWidth = containerElement.getBoundingClientRect().width;
Expand All @@ -1864,6 +1863,7 @@ describe('igxCombo', () => {
expect(dropDownWidth).toEqual(containerElementWidth);
expect(inputWidth).toEqual(containerElementWidth);
}));

it('Should render combo width properly when placed in container', fakeAsync(() => {
const fixture = TestBed.createComponent(IgxComboInContainerFixedWidthComponent);
fixture.detectChanges();
Expand Down
43 changes: 41 additions & 2 deletions projects/igniteui-angular/src/lib/combo/combo.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { OverlaySettings, AbsoluteScrollStrategy } from '../services';
import { Subscription } from 'rxjs';
import { DeprecateProperty } from '../core/deprecateDecorators';
import { DefaultSortingStrategy, ISortingStrategy } from '../data-operations/sorting-strategy';
import { DisplayDensityBase, DisplayDensityToken, IDisplayDensityOptions } from '../core/density';

/** Custom strategy to provide the combo with callback on initial positioning */
class ComboConnectedPositionStrategy extends ConnectedPositioningStrategy {
Expand Down Expand Up @@ -97,7 +98,7 @@ const noop = () => { };
selector: 'igx-combo',
templateUrl: 'combo.component.html'
})
export class IgxComboComponent implements AfterViewInit, ControlValueAccessor, OnInit, OnDestroy {
export class IgxComboComponent extends DisplayDensityBase implements AfterViewInit, ControlValueAccessor, OnInit, OnDestroy {
/**
* @hidden
*/
Expand Down Expand Up @@ -169,7 +170,9 @@ export class IgxComboComponent implements AfterViewInit, ControlValueAccessor, O
protected elementRef: ElementRef,
protected cdr: ChangeDetectorRef,
protected selection: IgxSelectionAPIService,
@Self() @Optional() public ngControl: NgControl) {
@Self() @Optional() public ngControl: NgControl,
@Optional() @Inject(DisplayDensityToken) protected _displayDensityOptions: IDisplayDensityOptions) {
super(_displayDensityOptions);
if (this.ngControl) {
// Note: we provide the value accessor through here, instead of
// the `providers` to avoid running into a circular import.
Expand Down Expand Up @@ -523,6 +526,42 @@ export class IgxComboComponent implements AfterViewInit, ControlValueAccessor, O
return this._valid === IgxComboState.INVALID;
}

/**
* @hidden
*/
@HostBinding('class.igx-combo')
public cssClass = 'igx-combo'; // Independant of display density, at the time being

/**
* @hidden
*/
@HostBinding(`attr.role`)
public role = 'combobox';

/**
* @hidden
*/
@HostBinding('attr.aria-expanded')
public get ariaExpanded() {
return !this.dropdown.collapsed;
}

/**
* @hidden
*/
@HostBinding('attr.aria-haspopup')
public get hasPopUp() {
return 'listbox';
}

/**
* @hidden
*/
@HostBinding('attr.aria-owns')
public get ariaOwns() {
return this.dropdown.id;
}

/**
* Controls whether custom values can be added to the collection
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@

%igx-combo {
position: relative;
display: block;

%igx-button--icon {
width: rem(24px);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,11 +163,17 @@ export class IgxGridGroupByRowComponent {
* this.grid1.rowList.first.toggle()
* ```
*/
public toggle(key?) {
const shouldExpand = (!key && !this.expanded) || (key && !this.expanded && (key === 'arrowleft' || key === 'left'));
this.handleToggleScroll();
if (!shouldExpand) {
this.grid.verticalScrollContainer.getVerticalScroll().dispatchEvent(new Event('scroll'));
public toggle() {
const isVirtualized = !this.grid.verticalScrollContainer.dc.instance.notVirtual;
const groupRowIndex = this.index;
this.grid.toggleGroup(this.groupRow);
if (isVirtualized) {
this.grid.verticalScrollContainer.onChunkLoad
.pipe(first())
.subscribe(() => {
const groupRow = this.grid.nativeElement.querySelector(`[data-rowIndex="${groupRowIndex}"]`);
if (groupRow) { groupRow.focus(); }
});
}
}

Expand All @@ -185,7 +191,10 @@ export class IgxGridGroupByRowComponent {

if (this.isToggleKey(key)) {
if (!alt) { return; }
this.toggle(key);
if ((this.expanded && (key === 'left' || key === 'arrowleft')) ||
(!this.expanded && (key === 'right' || key === 'arrowright'))) {
this.toggle();
}
return;
}
const args = { cell: null, groupRow: this, event: event, cancel: false };
Expand Down Expand Up @@ -252,16 +261,5 @@ export class IgxGridGroupByRowComponent {
private isToggleKey(key) {
return ['left', 'right', 'arrowleft', 'arrowright'].indexOf(key) !== -1;
}
private handleToggleScroll() {
if (this.grid.rowList.length > 0 && this.grid.rowList.last.index ===
this.grid.verticalScrollContainer.igxForOf.length - 1) {
const groupRowIndex = this.index;
this.grid.verticalScrollContainer.onChunkLoad
.pipe(first())
.subscribe(() => {
this.grid.nativeElement.querySelector(`[data-rowIndex="${groupRowIndex}"]`).focus();
});
}
this.grid.toggleGroup(this.groupRow);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,15 @@ export class IgxTreeGridAPIService extends GridBaseAPIService<IgxTreeGridCompone
grid.expansionStates = expandedStates;

if (isScrolledToBottom) {
grid.nativeElement.focus({preventScroll: true});
grid.verticalScrollContainer.onChunkLoad
.pipe(first())
.subscribe(() => {
grid.nativeElement.querySelector(
`[data-rowIndex="${groupRowIndex}"][data-visibleindex="${visibleColumnIndex}"]`).focus();
});
}
if (expanded) {
if (expanded || (!expanded && isScrolledToBottom)) {
grid.verticalScrollContainer.getVerticalScroll().dispatchEvent(new Event('scroll'));
if (shouldScroll) {
grid.parentVirtDir.getHorizontalScroll().dispatchEvent(new Event('scroll'));
Expand Down
7 changes: 7 additions & 0 deletions src/app/combo/combo.sample.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
(onAddition)="handleAddition($event)"
[data]="items"
[allowCustomValues]="true"
[displayDensity]="'comfortable'"
[filterable]="true" [displayKey]="valueKeyVar" [valueKey]="valueKeyVar"
[groupKey]="valueKeyVar ? 'region' : ''" [width]="'100%'">
<ng-template *ngIf="currentDataType !== 'primitive'" #itemTemplate let-display let-key="valueKey">
Expand Down Expand Up @@ -61,6 +62,12 @@
</div>
</ng-template>
</div>
<div>
<h4>Display Density</h4>
<button igxButton="raised" [disabled]="igxCombo.isCompact()" (click)="setDensity('compact')">Compact</button>
<button igxButton="raised" [disabled]="igxCombo.isCosy()" (click)="setDensity('cosy')">Cosy</button>
<button igxButton="raised" [disabled]="!igxCombo.isCosy() && !igxCombo.isCompact()" (click)="setDensity('comfortable')">Comfortable</button>
</div>
</section>
</div>
</div>
4 changes: 4 additions & 0 deletions src/app/combo/combo.sample.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,4 +121,8 @@ export class ComboSampleComponent implements OnInit {
this.igxCombo.itemTemplate = this.initialItemTemplate ? this.initialItemTemplate : this.customItemTemplate ;
this.initialItemTemplate = comboTemplate;
}

setDensity(density: string) {
this.igxCombo.displayDensity = density;
}
}

0 comments on commit 4f9f845

Please sign in to comment.