Skip to content

Commit ab84729

Browse files
authored
feat(input-group): type token implementation #6751 (#8051)
1 parent 577f4f8 commit ab84729

13 files changed

+137
-66
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ All notable changes for each version of this project will be documented in this
1111
### New Features
1212
- `IgxGrid`, `IgxTreeGrid`, `IgxHierarchicalGrid`
1313
- When triggering an export of the grid via the toolbar and the export takes more than 500 milliseconds, the export button becomes disabled and an indeterminate progress bar is shown at the bottom of the toolbar until the export is finished.
14+
- ` IGX_INPUT_GROUP_TYPE` injection token
15+
- Allows for setting an input group `type` on a global level, so all input-group instances, including components using such an instance as a template will have their input group type set to the one specified by the token. It can be overridden on a component level by explicitly setting a `type`.
1416
- ` IgxExcelExporterService`
1517
- Added `worksheetName` property to the `IgxExcelExporterOptions`, that allows setting the name of the worksheet.
1618

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

+36-18
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ describe('igxCombo', () => {
8888
mockSelection.get.and.returnValue(new Set([]));
8989
const mockIconService = new IgxIconService(null, null);
9090
it('should correctly implement interface methods - ControlValueAccessor ', () => {
91-
combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, mockIconService, null, mockInjector);
91+
combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService,
92+
mockIconService, null, null, mockInjector);
9293
spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null);
9394
combo.ngOnInit();
9495
expect(mockInjector.get).toHaveBeenCalledWith(NgControl, null);
@@ -133,7 +134,8 @@ describe('igxCombo', () => {
133134
pending('Convert existing form test here');
134135
});
135136
it('should properly call dropdown methods on toggle', () => {
136-
combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, mockIconService, null, mockInjector);
137+
combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService,
138+
mockIconService, null, null, mockInjector);
137139
const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['open', 'close', 'toggle']);
138140
spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null);
139141
combo.ngOnInit();
@@ -156,7 +158,8 @@ describe('igxCombo', () => {
156158
expect(combo.collapsed).toBe(false);
157159
});
158160
it(`should not focus search input when property autoFocusSearch=false`, () => {
159-
combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, mockIconService, null, mockInjector);
161+
combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService,
162+
mockIconService, null, null, mockInjector);
160163
const dropdownContainer = { nativeElement: { focus: () => { } } };
161164
combo['dropdownContainer'] = dropdownContainer;
162165
spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null);
@@ -175,7 +178,8 @@ describe('igxCombo', () => {
175178
expect(combo.focusSearchInput).toHaveBeenCalledTimes(1);
176179
});
177180
it('should call dropdown toggle with correct overlaySettings', () => {
178-
combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, mockIconService, null, mockInjector);
181+
combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService,
182+
mockIconService, null, null, mockInjector);
179183
const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['toggle']);
180184
spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null);
181185
combo.ngOnInit();
@@ -193,7 +197,8 @@ describe('igxCombo', () => {
193197
expect(combo.dropdown.toggle).toHaveBeenCalledWith(expectedSettings);
194198
});
195199
it('should properly get/set displayKey', () => {
196-
combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, mockIconService, null, mockInjector);
200+
combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService,
201+
mockIconService, null, null, mockInjector);
197202
spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null);
198203
combo.ngOnInit();
199204
combo.valueKey = 'field';
@@ -203,7 +208,8 @@ describe('igxCombo', () => {
203208
expect(combo.displayKey === combo.valueKey).toBeFalsy();
204209
});
205210
it('should properly call "writeValue" method', () => {
206-
combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, mockIconService, null, mockInjector);
211+
combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService,
212+
mockIconService, null, null, mockInjector);
207213
spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null);
208214
combo.ngOnInit();
209215
combo.data = data;
@@ -221,7 +227,8 @@ describe('igxCombo', () => {
221227
});
222228
it('should select items through setSelctedItem method', () => {
223229
const selectionService = new IgxSelectionAPIService();
224-
combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, mockIconService, null, mockInjector);
230+
combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService,
231+
mockIconService, null, null, mockInjector);
225232
const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']);
226233
spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null);
227234
combo.ngOnInit();
@@ -256,7 +263,8 @@ describe('igxCombo', () => {
256263
});
257264
it('should set selectedItems correctly on selectItems method call', () => {
258265
const selectionService = new IgxSelectionAPIService();
259-
combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, mockIconService, null, mockInjector);
266+
combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService,
267+
mockIconService, null, null, mockInjector);
260268
const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']);
261269
spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null);
262270
combo.ngOnInit();
@@ -281,7 +289,8 @@ describe('igxCombo', () => {
281289
});
282290
it('should fire onSelectionChange event on item selection', () => {
283291
const selectionService = new IgxSelectionAPIService();
284-
combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, mockIconService, null, mockInjector);
292+
combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService,
293+
mockIconService, null, null, mockInjector);
285294
const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']);
286295
spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null);
287296
combo.ngOnInit();
@@ -352,7 +361,8 @@ describe('igxCombo', () => {
352361
});
353362
it('should properly emit added and removed values in change event on single value selection', () => {
354363
const selectionService = new IgxSelectionAPIService();
355-
combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, mockIconService, null, mockInjector);
364+
combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService,
365+
mockIconService, null, null, mockInjector);
356366
const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']);
357367
spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null);
358368
combo.ngOnInit();
@@ -384,7 +394,8 @@ describe('igxCombo', () => {
384394
});
385395
it('should properly emit added and removed values in change event on multiple values selection', () => {
386396
const selectionService = new IgxSelectionAPIService();
387-
combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, mockIconService, null, mockInjector);
397+
combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService,
398+
mockIconService, null, null, mockInjector);
388399
const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']);
389400
spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null);
390401
combo.ngOnInit();
@@ -432,7 +443,8 @@ describe('igxCombo', () => {
432443
});
433444
it('should handle select/deselect ALL items', () => {
434445
const selectionService = new IgxSelectionAPIService();
435-
combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, mockIconService, null, mockInjector);
446+
combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService,
447+
mockIconService, null, null, mockInjector);
436448
const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']);
437449
spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null);
438450
combo.ngOnInit();
@@ -452,7 +464,8 @@ describe('igxCombo', () => {
452464
});
453465
it('should emit onSelectonChange event on select/deselect ALL items method call', () => {
454466
const selectionService = new IgxSelectionAPIService();
455-
combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, mockIconService, null, mockInjector);
467+
combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService,
468+
mockIconService, null, null, mockInjector);
456469
const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']);
457470
spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null);
458471
combo.ngOnInit();
@@ -489,7 +502,8 @@ describe('igxCombo', () => {
489502
});
490503
it('should properly handle selection manipulation through onSelectionChange emit', () => {
491504
const selectionService = new IgxSelectionAPIService();
492-
combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService, mockIconService, null, mockInjector);
505+
combo = new IgxComboComponent(elementRef, mockCdr, selectionService, mockComboService,
506+
mockIconService, null, null, mockInjector);
493507
const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']);
494508
spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null);
495509
combo.ngOnInit();
@@ -507,7 +521,8 @@ describe('igxCombo', () => {
507521
expect(combo.selectedItems()).toEqual([]);
508522
});
509523
it('should not throw error when setting data to null', () => {
510-
combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, mockIconService, null, mockInjector);
524+
combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService,
525+
mockIconService, null, null, mockInjector);
511526
spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null);
512527
combo.ngOnInit();
513528
let errorMessage = '';
@@ -522,7 +537,8 @@ describe('igxCombo', () => {
522537
expect(combo.data.length).toBe(0);
523538
});
524539
it('should not throw error when setting data to undefined', () => {
525-
combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, mockIconService, null, mockInjector);
540+
combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService,
541+
mockIconService, null, null, mockInjector);
526542
spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null);
527543
combo.ngOnInit();
528544
let errorMessage = '';
@@ -537,7 +553,8 @@ describe('igxCombo', () => {
537553
expect(combo.data.length).toBe(0);
538554
});
539555
it('should properly handleInputChange', () => {
540-
combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, mockIconService, null, mockInjector);
556+
combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService,
557+
mockIconService, null, null, mockInjector);
541558
const dropdown = jasmine.createSpyObj('IgxComboDropDownComponent', ['selectItem']);
542559
spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null);
543560
combo.ngOnInit();
@@ -573,7 +590,8 @@ describe('igxCombo', () => {
573590
expect(combo.onSearchInput.emit).toHaveBeenCalledTimes(2);
574591
});
575592
it('should be able to cancel onSearchInput', () => {
576-
combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService, mockIconService, null, mockInjector);
593+
combo = new IgxComboComponent(elementRef, mockCdr, mockSelection as any, mockComboService,
594+
mockIconService, null, null, mockInjector);
577595
spyOn(mockIconService, 'addSvgIconFromText').and.returnValue(null);
578596
combo.ngOnInit();
579597
combo.data = data;

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

+9-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import { IgxComboAddItemComponent } from './combo-add-item.component';
3838
import { IgxComboAPIService } from './combo.api';
3939
import { EditorProvider } from '../core/edit-provider';
4040
import { IgxInputState, IgxInputDirective } from '../directives/input/input.directive';
41+
import { IgxInputGroupType, IGX_INPUT_GROUP_TYPE } from '../input-group/public_api';
4142

4243
/**
4344
* @hidden
@@ -174,6 +175,7 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
174175
protected _prevInputValue = '';
175176
private _dataType = '';
176177
private _searchValue = '';
178+
private _type = null;
177179
private ngControl: NgControl = null;
178180
private destroy$ = new Subject<any>();
179181
private _data = [];
@@ -199,6 +201,7 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
199201
protected comboAPI: IgxComboAPIService,
200202
private _iconService: IgxIconService,
201203
@Optional() @Inject(DisplayDensityToken) protected _displayDensityOptions: IDisplayDensityOptions,
204+
@Optional() @Inject(IGX_INPUT_GROUP_TYPE) private _inputGroupType: IgxInputGroupType,
202205
@Optional() private _injector: Injector) {
203206
super(_displayDensityOptions);
204207
this.comboAPI.register(this);
@@ -859,8 +862,13 @@ export class IgxComboComponent extends DisplayDensityBase implements IgxComboBas
859862
* ```
860863
*/
861864
@Input()
862-
public type = 'box';
865+
public get type(): IgxInputGroupType {
866+
return this._type || this._inputGroupType || 'box';
867+
}
863868

869+
public set type(val: IgxInputGroupType) {
870+
this._type = val;
871+
}
864872
/**
865873
* An @Input property that controls whether the combo's search box
866874
* should be focused after the `onOpened` event is called

projects/igniteui-angular/src/lib/date-picker/date-picker.component.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1445,7 +1445,7 @@ describe('IgxDatePicker', () => {
14451445
};
14461446
moduleRef = {};
14471447
injector = { get: () => ngModel };
1448-
inputGroup = new IgxInputGroupComponent(null, null, document);
1448+
inputGroup = new IgxInputGroupComponent(null, null, null, document);
14491449
});
14501450

14511451
it('should initialize date picker with required correctly', () => {

projects/igniteui-angular/src/lib/input-group/input-group.component.spec.ts

+23-7
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1-
import { Component, ViewChild, ElementRef } from '@angular/core';
1+
import { Component, ViewChild, ElementRef, Inject } from '@angular/core';
22
import { async, TestBed } from '@angular/core/testing';
33
import { By } from '@angular/platform-browser';
4-
import { IgxInputGroupComponent, IgxInputGroupModule, IgxInputGroupType } from './input-group.component';
4+
import { IgxInputGroupComponent, IgxInputGroupModule } from './input-group.component';
55
import { DisplayDensityToken, DisplayDensity } from '../core/displayDensity';
66
import { UIInteractions } from '../test-utils/ui-interactions.spec';
77
import { IgxIconModule } from '../icon/public_api';
88
import { IgxInputDirective } from '../directives/input/input.directive';
99
import { configureTestSuite } from '../test-utils/configure-suite';
1010
import { IgxPrefixDirective, IgxSuffixDirective } from '../chips/public_api';
11+
import { IGX_INPUT_GROUP_TYPE, IgxInputGroupType } from './inputGroupType';
1112

1213
const INPUT_GROUP_CSS_CLASS = 'igx-input-group';
1314
const INPUT_GROUP_BOX_CSS_CLASS = 'igx-input-group--box';
@@ -40,7 +41,7 @@ describe('IgxInputGroup', () => {
4041
}));
4142

4243
it('Initializes an input group.', () => {
43-
const fixture = TestBed.createComponent(InputGroupComponent);
44+
const fixture = TestBed.createComponent(InputGroupDisabledComponent);
4445
fixture.detectChanges();
4546

4647
const inputGroupElement = fixture.debugElement.query(By.css('igx-input-group')).nativeElement;
@@ -86,28 +87,40 @@ describe('IgxInputGroup', () => {
8687
testInputGroupType('search', igxInputGroup, inputGroupElement);
8788
});
8889

89-
it('Should be able to change input group type programmatically.', () => {
90+
it('Should respect type Token and be able to change input group type programmatically.', () => {
9091
const fixture = TestBed.createComponent(InputGroupComponent);
9192
fixture.detectChanges();
9293

9394
const inputGroupElement = fixture.debugElement.query(By.css('igx-input-group')).nativeElement;
9495
const igxInputGroup = fixture.componentInstance.igxInputGroup;
9596

96-
igxInputGroup.type = 'box';
97-
fixture.detectChanges();
97+
// a Token is passed and can be obtained
98+
expect(fixture.componentInstance.IGTOKEN).toBe('box');
99+
100+
// type set via Token is 'box'
98101
testInputGroupType('box', igxInputGroup, inputGroupElement);
99102

103+
// user can override Token passing other igxInputGroup types
100104
igxInputGroup.type = 'border';
101105
fixture.detectChanges();
102106
testInputGroupType('border', igxInputGroup, inputGroupElement);
103107

108+
igxInputGroup.type = 'box';
109+
fixture.detectChanges();
110+
testInputGroupType('box', igxInputGroup, inputGroupElement);
111+
104112
igxInputGroup.type = 'search';
105113
fixture.detectChanges();
106114
testInputGroupType('search', igxInputGroup, inputGroupElement);
107115

108116
igxInputGroup.type = 'line';
109117
fixture.detectChanges();
110118
testInputGroupType('line', igxInputGroup, inputGroupElement);
119+
120+
// Set type as null, so the Token type should be used again
121+
igxInputGroup.type = null;
122+
fixture.detectChanges();
123+
testInputGroupType('box', igxInputGroup, inputGroupElement);
111124
});
112125

113126
it('disabled input should properly detect changes.', () => {
@@ -250,14 +263,17 @@ describe('IgxInputGroup', () => {
250263
<igx-prefix>PREFIX</igx-prefix>
251264
<igx-suffix>SUFFIX</igx-suffix>
252265
<input #igxInput igxInput />
253-
</igx-input-group>`
266+
</igx-input-group>`,
267+
providers: [{ provide: IGX_INPUT_GROUP_TYPE, useValue: 'box'}]
254268
})
255269
class InputGroupComponent {
256270
@ViewChild('igxInputGroup', { static: true }) public igxInputGroup: IgxInputGroupComponent;
257271
@ViewChild('igxInput', { read: IgxInputDirective, static: true }) public igxInput: IgxInputDirective;
258272
@ViewChild(IgxPrefixDirective, { read: ElementRef }) public prefix: ElementRef;
259273
@ViewChild(IgxSuffixDirective, { read: ElementRef }) public suffix: ElementRef;
260274
public suppressInputAutofocus = false;
275+
276+
constructor(@Inject(IGX_INPUT_GROUP_TYPE) public IGTOKEN: IgxInputGroupType) {}
261277
}
262278

263279
@Component({

0 commit comments

Comments
 (0)