Skip to content

Commit 2d082e4

Browse files
authored
Merge pull request #5036 from IgniteUI/add-density-to-drop-down_7.2.x
style(drop-down): Adding classes for different density types
2 parents 51f96f4 + 5615063 commit 2d082e4

26 files changed

+532
-91
lines changed

CHANGELOG.md

+9
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,15 @@ All notable changes for each version of this project will be documented in this
1313
### New features
1414
- **igxSlider** - exposing new `labels` property accepting a collection of literal values that become equally spread over the slider, by placing each element as a thumb label.
1515
- **igxSlider** - deprecate **isContiunous** property.
16+
- `IgxDropDown` now supports `DisplayDensity`.
17+
- `[displayDensity]` - `@Input()` added to the `igx-drop-down`. Takes prevelance over any other `DisplayDensity` provider (e.g. parent component or `DisplayDensityToken` provided in module)
18+
- The component can also get it's display density from Angular's DI engine (if the `DisplayDensityToken` is provided on a lower level)
19+
- Setting `[displayDensity]` affects the control's items' and inputs' css properties, most notably heights, padding, font-size
20+
- Available display densities are `compact`, `cosy` and `comfortable` (default)
21+
- **Behavioral Change** - default item `igx-drop-down-item` height is now `40px` (down from `48px`)
22+
- `IgxCombo` - Setting `[displayDensity]` now also affects the combo's items
23+
- Setting `[itemHeight]` overrides the height provided by the `[displayDensity]` input
24+
- `IgxSelect`- Setting `[displayDensity]` now also affects the select's items
1625

1726
### Bug Fixes
1827
- In slider with type Range when change the lower value to be equal or greater than the upper the range is not correct #4562

projects/igniteui-angular/src/lib/combo/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,10 @@ When igxCombo is opened, allow custom values are enabled and add item button is
233233

234234
- `ArrowUp` focus will be moved back to the last list item or if list is empty will be moved to the search input.
235235

236+
## Display Density
237+
**igx-combo** supports setting of different display densities.
238+
Display density is received through Angular's DI engine or can be set through the `[displayDensity]` input. The possilbe display densities are `compact`, `cosy` and `comfortable` (default).
239+
Setting `[displayDensity]` affects the control's items' and inputs' css properties, most notably heights, padding, font-size.
236240

237241
## API
238242

projects/igniteui-angular/src/lib/combo/combo-dropdown.component.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
2-
ChangeDetectorRef, Component, ContentChild, ElementRef, forwardRef, Inject, QueryList, OnDestroy, AfterViewInit, ContentChildren
2+
ChangeDetectorRef, Component, ElementRef, Inject, QueryList, OnDestroy, AfterViewInit, ContentChild, ContentChildren, Optional,
3+
forwardRef
34
} from '@angular/core';
45
import { takeUntil, take } from 'rxjs/operators';
56
import { IgxForOfDirective } from '../directives/for-of/for_of.directive';
@@ -14,6 +15,7 @@ import { IgxComboAPIService } from './combo.api';
1415
import { IgxDropDownItemBase } from '../drop-down/drop-down-item.base';
1516
import { IgxSelectionAPIService } from '../core/selection';
1617
import { IgxComboItemComponent } from './combo-item.component';
18+
import { DisplayDensityToken, IDisplayDensityOptions } from '../core/density';
1719

1820
/** @hidden */
1921
@Component({
@@ -27,8 +29,9 @@ export class IgxComboDropDownComponent extends IgxDropDownComponent implements I
2729
protected cdr: ChangeDetectorRef,
2830
protected selection: IgxSelectionAPIService,
2931
@Inject(IGX_COMBO_COMPONENT) public combo: IgxComboBase,
30-
protected comboAPI: IgxComboAPIService) {
31-
super(elementRef, cdr, selection);
32+
protected comboAPI: IgxComboAPIService,
33+
@Optional() @Inject(DisplayDensityToken) protected _displayDensityOptions: IDisplayDensityOptions) {
34+
super(elementRef, cdr, selection, _displayDensityOptions);
3235
}
3336

3437
protected get scrollContainer() {

projects/igniteui-angular/src/lib/combo/combo.component.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
<igx-icon *ngIf="!toggleIconTemplate" fontSet="material">{{ dropdown.collapsed ? 'arrow_drop_down' : 'arrow_drop_up'}}</igx-icon>
4343
</igx-suffix>
4444
</igx-input-group>
45-
<igx-combo-drop-down #igxComboDropDown class="igx-combo__drop-down" [width]="itemsWidth || '100%'" (onOpening)="handleOpening($event)"
45+
<igx-combo-drop-down #igxComboDropDown class="igx-combo__drop-down" [displayDensity]="displayDensity" [width]="itemsWidth || '100%'" (onOpening)="handleOpening($event)"
4646
(onClosing)="handleClosing($event)" (onOpened)="handleOpened()" (onClosed)="handleClosed()">
4747
<igx-input-group *ngIf="displaySearchInput" [displayDensity]="displayDensity" class="igx-combo__search">
4848
<input class="igx-combo-input" igxInput #searchInput name="searchInput" autocomplete="off" type="text"
@@ -58,7 +58,7 @@
5858
<ng-template igxFor let-item let-index="index" [igxForOf]="data | comboFiltering:filteringExpressions:filteringLogic | comboSorting:sortingExpressions | comboGrouping:groupKey"
5959
[igxForScrollOrientation]="'vertical'" [igxForContainerSize]="itemsMaxHeight" [igxForItemSize]="itemHeight"
6060
(onChunkPreload)="dataLoading($event)">
61-
<igx-combo-item [itemHeight]='itemHeight' [value]="item" isHeader={{item.isHeader}} role="option" [index]="index">
61+
<igx-combo-item [itemHeight]='itemHeight' [value]="item" [isHeader]="item.isHeader" role="option" [index]="index">
6262
<ng-container *ngIf="item.isHeader">
6363
<ng-container *ngTemplateOutlet="headerItemTemplate ? headerItemTemplate : headerItemBase; context: {$implicit: item, data: data, valueKey: valueKey, groupKey: groupKey, displayKey: displayKey}"></ng-container>
6464
</ng-container>

projects/igniteui-angular/src/lib/combo/combo.component.spec.ts

+97-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { DefaultSortingStrategy } from '../data-operations/sorting-strategy';
1616
import { configureTestSuite } from '../test-utils/configure-suite';
1717
import { IgxDropDownBase } from '../drop-down/drop-down.base';
1818
import { IgxDropDownItemBase } from '../drop-down/drop-down-item.base';
19+
import { DisplayDensity, DisplayDensityToken } from '../core/density';
1920

2021
const CSS_CLASS_COMBO = 'igx-combo';
2122
const CSS_CLASS_COMBO_DROPDOWN = 'igx-combo__drop-down';
@@ -41,6 +42,20 @@ const CSS_CLASS_INPUTGROUP_MAINBUNDLE = 'igx-input-group__bundle-main';
4142
const CSS_CLASS_INPUTGROUP_BORDER = 'igx-input-group__border';
4243
const CSS_CLASS_HEADER = 'header-class';
4344
const CSS_CLASS_FOOTER = 'footer-class';
45+
const CSS_CLASS_ITEM = 'igx-drop-down__item';
46+
const CSS_CLASS_ITEM_COSY = 'igx-drop-down__item--cosy';
47+
const CSS_CLASS_ITEM_COMPACT = 'igx-drop-down__item--compact';
48+
const CSS_CLASS_HEADER_ITEM = 'igx-drop-down__header';
49+
const CSS_CLASS_HEADER_COSY = 'igx-drop-down__header--cosy';
50+
const CSS_CLASS_HEADER_COMPACT = 'igx-drop-down__header--compact';
51+
const CSS_CLASS_INPUT_COSY = 'igx-input-group--cosy';
52+
const CSS_CLASS_INPUT_COMPACT = 'igx-input-group--compact';
53+
const CSS_CLASS_INPUT_COMFORTABLE = 'igx-input-group--comfortable';
54+
55+
const fiftyItems = Array.apply(null, { length: 50 }).map((e, i) => ({
56+
value: i,
57+
name: `Item ${i + 1}`
58+
}));
4459

4560
describe('igxCombo', () => {
4661
configureTestSuite();
@@ -58,7 +73,9 @@ describe('igxCombo', () => {
5873
IgxComboInContainerTestComponent,
5974
IgxComboInContainerFixedWidthComponent,
6075
IgxComboFormComponent,
61-
SimpleBindComboComponent
76+
SimpleBindComboComponent,
77+
DensityParentComponent,
78+
DensityInputComponent
6279
],
6380
imports: [
6481
IgxComboModule,
@@ -3097,6 +3114,57 @@ describe('igxCombo', () => {
30973114
expect(fixture.componentInstance.comboSelectedItems).toEqual([...data].splice(1, 3));
30983115
}));
30993116
});
3117+
3118+
describe('Combo - Display Density', () => {
3119+
it('Should be able to set Display Density as input', fakeAsync(() => {
3120+
const fixutre = TestBed.createComponent(DensityInputComponent);
3121+
tick();
3122+
fixutre.detectChanges();
3123+
const combo = fixutre.componentInstance.combo;
3124+
expect(combo.displayDensity).toEqual(DisplayDensity.cosy);
3125+
fixutre.componentInstance.density = DisplayDensity.compact;
3126+
tick();
3127+
fixutre.detectChanges();
3128+
expect(combo.displayDensity).toEqual(DisplayDensity.compact);
3129+
fixutre.componentInstance.density = DisplayDensity.comfortable;
3130+
tick();
3131+
fixutre.detectChanges();
3132+
expect(combo.displayDensity).toEqual(DisplayDensity.comfortable);
3133+
}));
3134+
it('Should be able to get Display Density from DI engine', fakeAsync(() => {
3135+
const fixutre = TestBed.createComponent(DensityInputComponent);
3136+
tick();
3137+
fixutre.detectChanges();
3138+
const combo = fixutre.componentInstance.combo;
3139+
expect(combo.displayDensity).toEqual(DisplayDensity.cosy);
3140+
}));
3141+
it('Should apply correct styles to items and input when Display Density is set', fakeAsync(() => {
3142+
const fixutre = TestBed.createComponent(DensityInputComponent);
3143+
tick();
3144+
fixutre.detectChanges();
3145+
const combo = fixutre.componentInstance.combo;
3146+
combo.toggle();
3147+
tick();
3148+
fixutre.detectChanges();
3149+
expect(combo.dropdown.items.length).toEqual(document.getElementsByClassName(CSS_CLASS_ITEM_COSY).length);
3150+
expect(combo.dropdown.headers.length).toEqual(document.getElementsByClassName(CSS_CLASS_HEADER_COSY).length);
3151+
expect(document.getElementsByClassName(CSS_CLASS_INPUT_COSY).length).toBe(2);
3152+
fixutre.componentInstance.density = DisplayDensity.compact;
3153+
tick();
3154+
fixutre.detectChanges();
3155+
expect(combo.dropdown.items.length).toEqual(document.getElementsByClassName(CSS_CLASS_ITEM_COMPACT).length);
3156+
expect(combo.dropdown.headers.length).toEqual(document.getElementsByClassName(CSS_CLASS_HEADER_COMPACT).length);
3157+
expect(document.getElementsByClassName(CSS_CLASS_INPUT_COMPACT).length).toBe(2);
3158+
fixutre.componentInstance.density = DisplayDensity.comfortable;
3159+
tick();
3160+
fixutre.detectChanges();
3161+
expect(combo.dropdown.items.length).toEqual(document.getElementsByClassName(CSS_CLASS_ITEM).length);
3162+
expect(combo.dropdown.headers.length).toEqual(document.getElementsByClassName(CSS_CLASS_HEADER_ITEM).length);
3163+
expect(document.getElementsByClassName(CSS_CLASS_INPUT_COMFORTABLE).length).toBe(2);
3164+
expect(document.getElementsByClassName(CSS_CLASS_ITEM_COMPACT).length).toEqual(0);
3165+
expect(document.getElementsByClassName(CSS_CLASS_ITEM_COSY).length).toEqual(0);
3166+
}));
3167+
});
31003168
});
31013169

31023170
@Component({
@@ -3603,3 +3671,31 @@ export class SimpleBindComboComponent implements OnInit {
36033671
this.comboSelectedItems = ['One', 'Two'];
36043672
}
36053673
}
3674+
3675+
@Component({
3676+
template: `
3677+
<igx-combo #combo [data]="items" [displayDensity]="density" [displayKey]="'name'" [valueKey]="'value'">
3678+
</igx-combo>
3679+
`
3680+
})
3681+
class DensityInputComponent {
3682+
public density = DisplayDensity.cosy;
3683+
@ViewChild('combo', { read: IgxComboComponent })
3684+
public combo: IgxComboComponent;
3685+
public items = fiftyItems;
3686+
}
3687+
3688+
@Component({
3689+
template: `
3690+
<igx-combo #combo [data]="items" [displayKey]="'name'" [valueKey]="'value'">
3691+
</igx-combo>
3692+
`,
3693+
providers: [{
3694+
provide: DisplayDensityToken, useValue: DisplayDensity.cosy
3695+
}]
3696+
})
3697+
class DensityParentComponent {
3698+
@ViewChild('combo', { read: IgxComboComponent })
3699+
public combo: IgxComboComponent;
3700+
public items = fiftyItems;
3701+
}

projects/igniteui-angular/src/lib/combo/combo.component.ts

+21-2
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import { IgxComboItemComponent } from './combo-item.component';
3232
import { IgxComboDropDownComponent } from './combo-dropdown.component';
3333
import { IgxComboFilterConditionPipe, IgxComboFilteringPipe, IgxComboGroupingPipe, IgxComboSortingPipe } from './combo.pipes';
3434
import { OverlaySettings, AbsoluteScrollStrategy } from '../services';
35-
import { Subject, Subscription } from 'rxjs';
35+
import { Subject } from 'rxjs';
3636
import { takeUntil } from 'rxjs/operators';
3737
import { DeprecateProperty } from '../core/deprecateDecorators';
3838
import { DefaultSortingStrategy, ISortingStrategy } from '../data-operations/sorting-strategy';
@@ -69,6 +69,15 @@ enum DataTypes {
6969
PRIMARYKEY = 'valueKey'
7070
}
7171

72+
/**
73+
* @hidden
74+
*/
75+
const ItemHeights = {
76+
'comfortable': 48,
77+
'cosy': 32,
78+
'compact': 28,
79+
};
80+
7281
export enum IgxComboState {
7382
/**
7483
* Combo with initial state.
@@ -131,6 +140,7 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
131140
private destroy$ = new Subject<any>();
132141
private _data = [];
133142
private _filteredData = [];
143+
private _itemHeight = null;
134144
private _positionCallback: () => void;
135145
private _onChangeCallback: (_: any) => void = noop;
136146
private overlaySettings: OverlaySettings = {
@@ -670,7 +680,16 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
670680
* ```
671681
*/
672682
@Input()
673-
public itemHeight = 48;
683+
public get itemHeight(): number {
684+
if (this._itemHeight === null || this._itemHeight === undefined) {
685+
return ItemHeights[this.displayDensity];
686+
}
687+
return this._itemHeight;
688+
}
689+
690+
public set itemHeight(val: number) {
691+
this._itemHeight = val;
692+
}
674693

675694
/**
676695
* @hidden @internal

projects/igniteui-angular/src/lib/core/styles/components/drop-down/_drop-down-component.scss

+16
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@
2424
@extend %igx-drop-down__item !optional;
2525
}
2626

27+
@include e(item, $m: cosy) {
28+
@extend %igx-drop-down__item--cosy !optional;
29+
}
30+
31+
@include e(item, $m: compact) {
32+
@extend %igx-drop-down__item--compact !optional;
33+
}
34+
2735
@include e(item, $m: focused) {
2836
@extend %igx-drop-down__item--focused !optional;
2937
}
@@ -44,6 +52,14 @@
4452
@extend %igx-drop-down__header !optional;
4553
}
4654

55+
@include e(header, $m: cosy) {
56+
@extend %igx-drop-down__header--cosy !optional;
57+
}
58+
59+
@include e(header, $m: compact) {
60+
@extend %igx-drop-down__header--compact !optional;
61+
}
62+
4763
@include e(group) {
4864
@extend %igx-drop-down__group !optional;
4965
}

0 commit comments

Comments
 (0)