Skip to content

Commit 47c227f

Browse files
authored
Merge pull request #5248 from IgniteUI/vslavov/combo-expose-overlay
refactor(combo): expose overlay settings
2 parents 27be555 + ca0db5d commit 47c227f

File tree

6 files changed

+94
-34
lines changed

6 files changed

+94
-34
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ All notable changes for each version of this project will be documented in this
1414
- `IgxGrid`
1515
- `IgxColumnGroup`
1616
- Re-templating the column group header is now possible using the `headerTemplate` input property or the `igxHeader` directive.
17+
- `IgxCombo`
18+
- Input `[overlaySettings]` - allows an object of type `OverlaySettings` to be passed. These custom overlay settings control how the drop-down list displays.
1719

1820
## 8.0.2
1921
- `igx-list-theme` now have some new parameters for styling.

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ Setting `[displayDensity]` affects the control's items' and inputs' css properti
265265
| `ariaLabelledBy` | defines label ID related to combo | boolean |
266266
| `type` | Combo style. - "line", "box", "border", "search" | string |
267267
| `valid` | gets if control is valid, when used in a form | boolean |
268+
| `overlaySettings` | gets/sets the custom overlay settings that control how the drop-down list displays | OverlaySettings |
268269

269270
### Getters
270271
| Name | Description | Type |

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

Lines changed: 18 additions & 0 deletions
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 { IgxDropDownItemBase } from '../drop-down/drop-down-item.base';
1818
import { DisplayDensity, DisplayDensityToken } from '../core/density';
19+
import { AbsoluteScrollStrategy, ConnectedPositioningStrategy } from '../services/index';
1920

2021
const CSS_CLASS_COMBO = 'igx-combo';
2122
const CSS_CLASS_COMBO_DROPDOWN = 'igx-combo__drop-down';
@@ -185,6 +186,23 @@ describe('igxCombo', () => {
185186
expect(combo.displayKey).toEqual('region');
186187
expect(combo.displayKey === combo.valueKey).toBeFalsy();
187188
});
189+
it('Should properly get/set overlaySettings', () => {
190+
const fixture = TestBed.createComponent(IgxComboTestComponent);
191+
fixture.detectChanges();
192+
const combo = fixture.componentInstance.combo;
193+
const defaultSettings = (combo as any)._overlaySettings;
194+
spyOn(combo.dropdown, 'toggle');
195+
combo.toggle();
196+
expect(combo.dropdown.toggle).toHaveBeenCalledWith(defaultSettings);
197+
const newSettings = {
198+
positionStrategy: new ConnectedPositioningStrategy({ target: fixture.elementRef.nativeElement}),
199+
scrollStrategy: new AbsoluteScrollStrategy(fixture.elementRef.nativeElement)
200+
};
201+
combo.overlaySettings = newSettings;
202+
const expectedSettings = Object.assign({}, defaultSettings, newSettings);
203+
combo.toggle();
204+
expect(combo.dropdown.toggle).toHaveBeenCalledWith(expectedSettings);
205+
});
188206

189207
describe('EditorProvider', () => {
190208
it('Should return correct edit element', () => {

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

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -42,22 +42,6 @@ import { IgxComboAPIService } from './combo.api';
4242
import { EditorProvider } from '../core/edit-provider';
4343
import { take } from 'rxjs/operators';
4444

45-
/** Custom strategy to provide the combo with callback on initial positioning */
46-
class ComboConnectedPositionStrategy extends ConnectedPositioningStrategy {
47-
private _callback: () => void;
48-
constructor(callback: () => void) {
49-
super();
50-
this._callback = callback;
51-
}
52-
53-
position(contentElement, size, document?, initialCall?) {
54-
if (initialCall) {
55-
this._callback();
56-
}
57-
super.position(contentElement, size);
58-
}
59-
}
60-
6145
/**
6246
* @hidden
6347
*/
@@ -124,7 +108,7 @@ const noop = () => { };
124108
]
125109
})
126110
export class IgxComboComponent extends DisplayDensityBase implements IgxComboBase, AfterViewInit, ControlValueAccessor, OnInit,
127-
OnDestroy, EditorProvider {
111+
OnDestroy, EditorProvider {
128112
/**
129113
* @hidden @internal
130114
*/
@@ -148,10 +132,10 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
148132
private _filteredData = [];
149133
private _itemHeight = null;
150134
private _itemsMaxHeight = null;
151-
private _positionCallback: () => void;
152135
private _onChangeCallback: (_: any) => void = noop;
153-
private overlaySettings: OverlaySettings = {
136+
private _overlaySettings: OverlaySettings = {
154137
scrollStrategy: new AbsoluteScrollStrategy(),
138+
positionStrategy: new ConnectedPositioningStrategy(),
155139
modal: false,
156140
closeOnOutsideClick: true,
157141
excludePositionTarget: true
@@ -171,6 +155,26 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
171155
@ViewChild(IgxForOfDirective, { read: IgxForOfDirective, static: true })
172156
protected virtDir: IgxForOfDirective<any>;
173157

158+
/**
159+
* Set custom overlay settings that control how the combo's list of items is displayed.
160+
* Set:
161+
* ```html
162+
* <igx-combo [overlaySettings] = "customOverlaySettings"></igx-combo>
163+
* ```
164+
*
165+
* ```typescript
166+
* const customSettings = { positionStrategy: { settings: { target: myTarget } } };
167+
* combo.overlaySettings = customSettings;
168+
* ```
169+
* Get any custom overlay settings used by the combo:
170+
* ```typescript
171+
* const comboOverlaySettings: OverlaySettings = myCombo.overlaySettings;
172+
* ```
173+
*/
174+
175+
@Input()
176+
public overlaySettings: OverlaySettings = null;
177+
174178
/**
175179
* @hidden @internal
176180
*/
@@ -1249,9 +1253,7 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
12491253
*/
12501254
public ngOnInit() {
12511255
this.ngControl = this.injector.get(NgControl, null);
1252-
this._positionCallback = () => this.dropdown.updateScrollPosition();
1253-
this.overlaySettings.positionStrategy = new ComboConnectedPositionStrategy(this._positionCallback);
1254-
this.overlaySettings.positionStrategy.settings.target = this.elementRef.nativeElement;
1256+
this._overlaySettings.positionStrategy.settings.target = this.elementRef.nativeElement;
12551257
this.selection.set(this.id, new Set());
12561258
}
12571259

@@ -1263,7 +1265,7 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
12631265

12641266
if (this.ngControl) {
12651267
this.ngControl.statusChanges.pipe(takeUntil(this.destroy$)).subscribe(this.onStatusChanged);
1266-
}
1268+
}
12671269
}
12681270

12691271
/**
@@ -1358,7 +1360,8 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
13581360
*```
13591361
*/
13601362
public toggle(): void {
1361-
this.dropdown.toggle(this.overlaySettings);
1363+
const overlaySettings = Object.assign({}, this._overlaySettings, this.overlaySettings);
1364+
this.dropdown.toggle(overlaySettings);
13621365
}
13631366

13641367
/**
@@ -1370,7 +1373,8 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
13701373
*```
13711374
*/
13721375
public open(): void {
1373-
this.dropdown.open(this.overlaySettings);
1376+
const overlaySettings = Object.assign({}, this._overlaySettings, this.overlaySettings);
1377+
this.dropdown.open(overlaySettings);
13741378
}
13751379

13761380
/**

src/app/combo/combo.sample.html

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,21 @@ <h4>Search Input</h4>
7878
<igx-switch [(ngModel)]="filterableFlag">Filterable</igx-switch><br/>
7979
<igx-switch [(ngModel)]="customValuesFlag">Custom Values</igx-switch>
8080
</div>
81+
<div>
82+
<h4>Overlay Settings</h4>
83+
<button igxButton="raised" (click)="changeOverlaySettings(1)">Elastic Top</button>
84+
<button igxButton="raised" (click)="changeOverlaySettings(2)">Global with Animations</button>
85+
<button igxButton="raised" (click)="changeOverlaySettings(0)">Initial</button>
86+
</div>
87+
<div>
88+
<h4>Item Height</h4>
89+
<button igxButton="raised" [disabled]="combo.itemHeight === 56" (click)="combo.itemHeight = 56">
90+
Set ItemHeight to 56
91+
</button>
92+
<button igxButton="raised" [disabled]="combo.itemHeight === null" (click)="combo.itemHeight = null">
93+
Reset ItemHeight
94+
</button>
95+
</div>
8196
</section>
8297
</div>
83-
<button igxButton (click)="combo.itemHeight = 56">
84-
Set ItemHeight to 56
85-
</button>
86-
<button igxButton (click)="combo.itemHeight = null">
87-
Reset ItemHeight
88-
</button>
8998
</div>

src/app/combo/combo.sample.ts

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
import { Component, ViewChild, OnInit, TemplateRef } from '@angular/core';
2-
import { IgxComboComponent, IComboSelectionChangeEventArgs, DisplayDensity } from 'igniteui-angular';
1+
import { Component, ViewChild, OnInit, TemplateRef, AfterViewInit, ElementRef } from '@angular/core';
2+
import { IgxComboComponent, IComboSelectionChangeEventArgs,
3+
DisplayDensity, OverlaySettings, AutoPositionStrategy, VerticalAlignment, HorizontalAlignment, GlobalPositionStrategy,
4+
scaleInCenter, scaleOutCenter, ElasticPositionStrategy
5+
} from 'igniteui-angular';
36
import { take } from 'rxjs/operators';
7+
import { cloneDeep } from 'lodash';
48

59
const primitive = ['1', '2', '3', '4', '5', '6'];
610
const complex = [{
@@ -28,10 +32,12 @@ const complex = [{
2832
templateUrl: './combo.sample.html',
2933
styleUrls: ['combo.sample.css']
3034
})
31-
export class ComboSampleComponent implements OnInit {
35+
export class ComboSampleComponent implements OnInit, AfterViewInit {
36+
private overlaySettings: OverlaySettings[] = [null, null, null];
3237
private width = '160px';
3338
@ViewChild(IgxComboComponent, { static: true }) public igxCombo: IgxComboComponent;
3439
@ViewChild('comboTemplate', { read: IgxComboComponent, static: false }) public comboTemplate: IgxComboComponent;
40+
@ViewChild(IgxComboComponent, { read: ElementRef, static: true }) private comboRef: ElementRef;
3541
public toggleItemState = false;
3642
private initData: any[] = [];
3743
public filterableFlag = true;
@@ -123,6 +129,26 @@ export class ComboSampleComponent implements OnInit {
123129
});
124130
}
125131

132+
ngAfterViewInit() {
133+
this.overlaySettings[0] = cloneDeep(this.igxCombo.overlaySettings);
134+
this.overlaySettings[1] = {
135+
positionStrategy: new ElasticPositionStrategy({ target: this.comboRef.nativeElement,
136+
verticalDirection: VerticalAlignment.Top, verticalStartPoint: VerticalAlignment.Bottom,
137+
horizontalDirection: HorizontalAlignment.Left, horizontalStartPoint: HorizontalAlignment.Right }),
138+
modal: false,
139+
closeOnOutsideClick: true,
140+
};
141+
this.overlaySettings[2] = {
142+
positionStrategy: new GlobalPositionStrategy({ openAnimation: scaleInCenter, closeAnimation: scaleOutCenter }),
143+
modal: true,
144+
closeOnOutsideClick: true,
145+
};
146+
}
147+
148+
changeOverlaySettings(index: number) {
149+
this.igxCombo.overlaySettings = this.overlaySettings[index];
150+
}
151+
126152
changeItemTemplate() {
127153
const comboTemplate = this.initialItemTemplate ? null : this.igxCombo.itemTemplate;
128154
this.igxCombo.itemTemplate = this.initialItemTemplate ? this.initialItemTemplate : this.customItemTemplate ;

0 commit comments

Comments
 (0)