diff --git a/projects/igniteui-angular/src/lib/combo/combo.component.html b/projects/igniteui-angular/src/lib/combo/combo.component.html index a64a4fbaf04..e2fc4d7a9fb 100644 --- a/projects/igniteui-angular/src/lib/combo/combo.component.html +++ b/projects/igniteui-angular/src/lib/combo/combo.component.html @@ -14,58 +14,58 @@ {{ item[key] }} -
- - - - clear - - - arrow_drop_down - - arrow_drop_up - - + + + + clear + + + arrow_drop_down + + arrow_drop_up + + + + + + - - - - - - -
- - - - - - - - - - - - - -
-
-
- + + +
+ + + + + + + -
- - + + + +
+
+
+ +
- - - -
+ + + + +
+ + +
\ No newline at end of file diff --git a/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts b/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts index 5581a24184f..46ed19ff13d 100644 --- a/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts +++ b/projects/igniteui-angular/src/lib/combo/combo.component.spec.ts @@ -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(); @@ -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); @@ -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(); @@ -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; @@ -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(); diff --git a/projects/igniteui-angular/src/lib/combo/combo.component.ts b/projects/igniteui-angular/src/lib/combo/combo.component.ts index 4305db13f5e..0370cc7907d 100644 --- a/projects/igniteui-angular/src/lib/combo/combo.component.ts +++ b/projects/igniteui-angular/src/lib/combo/combo.component.ts @@ -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 { @@ -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 */ @@ -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. @@ -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 * diff --git a/projects/igniteui-angular/src/lib/core/styles/components/combo/_combo-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/combo/_combo-theme.scss index 2ca6d1c2689..5bae989394e 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/combo/_combo-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/combo/_combo-theme.scss @@ -38,6 +38,7 @@ %igx-combo { position: relative; + display: block; %igx-button--icon { width: rem(24px); diff --git a/projects/igniteui-angular/src/lib/grids/grid/groupby-row.component.ts b/projects/igniteui-angular/src/lib/grids/grid/groupby-row.component.ts index b3e90c922be..0e3cbae41f0 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/groupby-row.component.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/groupby-row.component.ts @@ -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(); } + }); } } @@ -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 }; @@ -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); - } + } diff --git a/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid-api.service.ts b/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid-api.service.ts index 85114348e66..d7c56066018 100644 --- a/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid-api.service.ts +++ b/projects/igniteui-angular/src/lib/grids/tree-grid/tree-grid-api.service.ts @@ -76,6 +76,7 @@ export class IgxTreeGridAPIService extends GridBaseAPIService { @@ -83,7 +84,7 @@ export class IgxTreeGridAPIService extends GridBaseAPIService @@ -61,6 +62,12 @@
+
+

Display Density

+ + + +
diff --git a/src/app/combo/combo.sample.ts b/src/app/combo/combo.sample.ts index 4fdc699e818..ffe254313b8 100644 --- a/src/app/combo/combo.sample.ts +++ b/src/app/combo/combo.sample.ts @@ -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; + } }