Skip to content

Commit 4c3c372

Browse files
authored
Merge branch 'master' into mpopov/indigo-calendar-updates
2 parents 04cd75c + 514efdb commit 4c3c372

File tree

9 files changed

+152
-53
lines changed

9 files changed

+152
-53
lines changed

CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ All notable changes for each version of this project will be documented in this
1818
`filterCell`, `headerCell`, `headerGroup`, `defaultMinWidth`, `gridRowSpan`, `gridColumnSpan` and `cells`.
1919
- `IgxPaginator`
2020
- The `isFirstPageDisabled` and `isLastPageDisabled` have been deprecated in favor of the identical `isFirstPage` and `isLastPage` getter.
21-
21+
- `IgxOverlayService`
22+
- The `attach` method overload accepting `Type` and `OverlaySettings` now accepts `OverlayCreateSettings` as second parameter. This interface extends `OverlaySettings` with an additional `injector` property used as `ElementInjector` when creating the dynamic component.
2223

2324
## 18.0.0
2425
### New Features

projects/igniteui-angular/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@
9494
}
9595
},
9696
"igxDevDependencies": {
97-
"@igniteui/angular-schematics": "~18.0.1330"
97+
"@igniteui/angular-schematics": "~18.1.1340"
9898
},
9999
"ng-update": {
100100
"migrations": "./migrations/migration-collection.json",

projects/igniteui-angular/src/lib/grids/state-base.directive.ts

-1
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,6 @@ interface Feature {
113113
/* blazorIndirectRender */
114114
@Directive()
115115
export class IgxGridStateBaseDirective {
116-
private static ngAcceptInputType_options: IGridStateOptions | '';
117116

118117
private featureKeys: GridFeatures[] = [];
119118
private state: IGridState;

projects/igniteui-angular/src/lib/grids/state.directive.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { GridFeatures, IGridState, IGridStateOptions, IgxGridStateBaseDirective
66
standalone: true
77
})
88
export class IgxGridStateDirective extends IgxGridStateBaseDirective {
9-
9+
private static ngAcceptInputType_options: IGridStateOptions | '';
1010

1111
/**
1212
* An object with options determining if a certain feature state should be saved.
@@ -17,14 +17,14 @@ export class IgxGridStateDirective extends IgxGridStateBaseDirective {
1717
* public options = {selection: false, advancedFiltering: false};
1818
* ```
1919
*/
20-
@Input('igxGridState')
21-
public get stateOptions(): IGridStateOptions {
22-
return super.options;
23-
}
20+
@Input('igxGridState')
21+
public override get options(): IGridStateOptions {
22+
return super.options;
23+
}
2424

25-
public set stateOptions(value: IGridStateOptions) {
26-
super.options = value;
27-
}
25+
public override set options(value: IGridStateOptions) {
26+
super.options = value;
27+
}
2828

2929
/**
3030
* Gets the state of a feature or states of all grid features, unless a certain feature is disabled through the `options` property.

projects/igniteui-angular/src/lib/services/overlay/README.md

+10-4
Original file line numberDiff line numberDiff line change
@@ -84,16 +84,22 @@ this.overlay.show(component, overlaySettings);
8484
|closeAnimation | AnimationMetadata | AnimationMetadata[] | Animation applied while overlay closes |
8585
|minSize | Size | The size up to which element may shrink when shown in elastic position strategy |
8686

87+
###### OverlayCreateSettings extends OverlaySettings
88+
89+
| Name | Type | Description |
90+
| :--- | :--- | :---------- |
91+
|injector | Injector | An `Injector` instance to add in the created component ref's injectors tree |
8792

8893
##### Methods
8994

9095
###### IgxOverlayService
9196

9297
| Name | Description | Parameters |
9398
|-----------------|---------------------------------------------------------------------------------|-----------------|
94-
|attach | Generates Id. Provide this Id when call `show(id, settings?)` method |element, overlaySettings? |
95-
|attach | Generates Id. Provide this Id when call `show(id, settings?)` method |component, overlaySettings?, moduleRef? |
96-
|show | Shows the provided component on the overlay |id, overlaySettings?|
99+
|attach | Generates Id. Provide this Id when call `show(id, settings?)` method |element, overlaySettings? |
100+
|attach | Generates Id. Provide this Id when call `show(id, settings?)` method |component, overlayCreateSettings?, |
101+
|attach | Generates Id. Provide this Id when call `show(id, settings?)` method |component, viewContainerRef, overlaySettings? |
102+
|show | Shows the provided component on the overlay |id, overlaySettings?|
97103
|hide | Hides the component with the ID provided as a parameter |id |
98104
|hideAll | Hides all the components and the overlay |- |
99105
|detach | Remove overlay with the provided id |id |
@@ -134,6 +140,6 @@ this.overlay.show(component, overlaySettings);
134140
| opened | Emitted after overlay shows | false | |
135141
| closing | Emitted before overlay hides | true | |
136142
| closed | Emitted after overlay hides | false | |
137-
| contentAppending | Emitted before overlay's content is appended | false | |
143+
| contentAppending | Emitted before overlay's content is appended | false | |
138144
| contentAppended | Emitted after overlay's content is appended | false | |
139145
| animationStarting | Emitted before animation is started | false | |

projects/igniteui-angular/src/lib/services/overlay/overlay.spec.ts

+78-4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
ElementRef,
55
HostBinding,
66
Inject,
7+
Injector,
78
ViewChild,
89
ViewContainerRef,
910
ViewEncapsulation
@@ -626,8 +627,10 @@ describe('igxOverlay', () => {
626627
expect(overlayInstance.contentAppending.emit).toHaveBeenCalledTimes(1);
627628
expect(overlayInstance.contentAppended.emit).toHaveBeenCalledTimes(1);
628629

629-
expect(overlayInstance.contentAppending.emit).toHaveBeenCalledWith({ id: firstCallId, elementRef: jasmine.any(Object),
630-
componentRef: jasmine.any(ComponentRef) as any, settings: os })
630+
expect(overlayInstance.contentAppending.emit).toHaveBeenCalledWith({
631+
id: firstCallId, elementRef: jasmine.any(Object),
632+
componentRef: jasmine.any(ComponentRef) as any, settings: os
633+
})
631634
}));
632635

633636
it('Should properly be able to override OverlaySettings using contentAppending event args', fakeAsync(() => {
@@ -1170,6 +1173,76 @@ describe('igxOverlay', () => {
11701173
overlay.detachAll();
11711174
});
11721175

1176+
it('#14364 - Should provide injector to attach method', () => {
1177+
const fixture = TestBed.createComponent(EmptyPageComponent);
1178+
const overlay = fixture.componentInstance.overlay;
1179+
const injector = Injector.create({
1180+
parent: fixture.componentInstance.injector,
1181+
providers: [
1182+
{ provide: 'SomeConst', useValue: 100 },
1183+
],
1184+
});
1185+
fixture.detectChanges();
1186+
1187+
const id = overlay.attach(SimpleDynamicComponent, { injector });
1188+
expect(id).toBeDefined();
1189+
1190+
const overlayInfo = overlay.getOverlayById(id);
1191+
expect(overlayInfo).toBeDefined();
1192+
1193+
const elementInjector = overlayInfo.componentRef.injector;
1194+
expect(elementInjector).toBeDefined();
1195+
1196+
const result = elementInjector.get('SomeConst');
1197+
expect(result).toEqual(100);
1198+
1199+
overlay.detachAll();
1200+
});
1201+
1202+
it('#14364 - Should provide different injectors to attach method to each component', () => {
1203+
const fixture = TestBed.createComponent(EmptyPageComponent);
1204+
const overlay = fixture.componentInstance.overlay;
1205+
const injector1 = Injector.create({
1206+
parent: fixture.componentInstance.injector,
1207+
providers: [
1208+
{ provide: 'SomeConst', useValue: 'First Value' },
1209+
],
1210+
});
1211+
const injector2 = Injector.create({
1212+
parent: fixture.componentInstance.injector,
1213+
providers: [
1214+
{ provide: 'SomeConst', useValue: 'Second Value' },
1215+
],
1216+
});
1217+
fixture.detectChanges();
1218+
1219+
const id1 = overlay.attach(SimpleDynamicComponent, { injector: injector1 });
1220+
expect(id1).toBeDefined();
1221+
1222+
const overlayInfo1 = overlay.getOverlayById(id1);
1223+
expect(overlayInfo1).toBeDefined();
1224+
1225+
const elementInjector1 = overlayInfo1.componentRef.injector;
1226+
expect(elementInjector1).toBeDefined();
1227+
1228+
const result1 = elementInjector1.get('SomeConst');
1229+
expect(result1).toEqual('First Value');
1230+
1231+
const id2 = overlay.attach(SimpleDynamicComponent, { injector: injector2 });
1232+
expect(id2).toBeDefined();
1233+
1234+
const overlayInfo2 = overlay.getOverlayById(id2);
1235+
expect(overlayInfo2).toBeDefined();
1236+
1237+
const elementInjector2 = overlayInfo2.componentRef.injector;
1238+
expect(elementInjector2).toBeDefined();
1239+
1240+
const result2 = elementInjector2.get('SomeConst');
1241+
expect(result2).toEqual('Second Value');
1242+
1243+
overlay.detachAll();
1244+
});
1245+
11731246
// it('##6474 - should calculate correctly position', () => {
11741247
// const elastic: ElasticPositionStrategy = new ElasticPositionStrategy();
11751248
// const targetRect: ClientRect = {
@@ -4391,7 +4464,7 @@ export class SimpleDynamicComponent {
43914464
public hostDisplay = 'block';
43924465
@HostBinding('style.width')
43934466
@HostBinding('style.height')
4394-
public hostDimenstions = '100px';
4467+
public hostDimensions = '100px';
43954468
}
43964469

43974470
@Component({
@@ -4481,7 +4554,8 @@ export class EmptyPageComponent {
44814554

44824555
constructor(
44834556
@Inject(IgxOverlayService) public overlay: IgxOverlayService,
4484-
public viewContainerRef: ViewContainerRef) { }
4557+
public viewContainerRef: ViewContainerRef,
4558+
public injector: Injector) { }
44854559

44864560
public click() {
44874561
this.overlay.show(this.overlay.attach(SimpleDynamicComponent));

projects/igniteui-angular/src/lib/services/overlay/overlay.ts

+37-24
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
EventEmitter,
99
Inject,
1010
Injectable,
11+
Injector,
1112
NgZone,
1213
OnDestroy,
1314
Type,
@@ -16,6 +17,7 @@ import {
1617
import { fromEvent, Subject, Subscription } from 'rxjs';
1718
import { filter, takeUntil } from 'rxjs/operators';
1819

20+
import { fadeIn, fadeOut, IAnimationParams, scaleInHorLeft, scaleInHorRight, scaleInVerBottom, scaleInVerTop, scaleOutHorLeft, scaleOutHorRight, scaleOutVerBottom, scaleOutVerTop, slideInBottom, slideInTop, slideOutBottom, slideOutTop } from 'igniteui-angular/animations';
1921
import { PlatformUtil } from '../../core/utils';
2022
import { IgxOverlayOutletDirective } from '../../directives/toggle/toggle.directive';
2123
import { IgxAngularAnimationService } from '../animation/angular-animation-service';
@@ -34,6 +36,7 @@ import {
3436
OverlayAnimationEventArgs,
3537
OverlayCancelableEventArgs,
3638
OverlayClosingEventArgs,
39+
OverlayCreateSettings,
3740
OverlayEventArgs,
3841
OverlayInfo,
3942
OverlaySettings,
@@ -43,7 +46,6 @@ import {
4346
RelativePositionStrategy,
4447
VerticalAlignment
4548
} from './utilities';
46-
import { fadeIn, fadeOut, IAnimationParams, scaleInHorLeft, scaleInHorRight, scaleInVerBottom, scaleInVerTop, scaleOutHorLeft, scaleOutHorRight, scaleOutVerBottom, scaleOutVerTop, slideInBottom, slideInTop, slideOutBottom, slideOutTop } from 'igniteui-angular/animations';
4749

4850
/**
4951
* [Documentation](https://www.infragistics.com/products/ignite-ui-angular/angular/components/overlay-main)
@@ -144,7 +146,7 @@ export class IgxOverlayService implements OnDestroy {
144146
@Inject(DOCUMENT) private document: any,
145147
private _zone: NgZone,
146148
protected platformUtil: PlatformUtil,
147-
@Inject(IgxAngularAnimationService)private animationService: AnimationService) {
149+
@Inject(IgxAngularAnimationService) private animationService: AnimationService) {
148150
this._document = this.document;
149151
}
150152

@@ -298,7 +300,7 @@ export class IgxOverlayService implements OnDestroy {
298300
* Generates Id. Provide this Id when call `show(id)` method
299301
*
300302
* @param component ElementRef to show in overlay
301-
* @param settings Display settings for the overlay, such as positioning and scroll/close behavior.
303+
* @param settings (optional): Display settings for the overlay, such as positioning and scroll/close behavior.
302304
* @returns Id of the created overlay. Valid until `detach` is called.
303305
*/
304306
public attach(element: ElementRef, settings?: OverlaySettings): string;
@@ -308,23 +310,25 @@ export class IgxOverlayService implements OnDestroy {
308310
* Note created instance is in root scope, prefer the `viewContainerRef` overload when local injection context is needed.
309311
*
310312
* @param component Component Type to show in overlay
311-
* @param settings Display settings for the overlay, such as positioning and scroll/close behavior.
313+
* @param settings (optional): Create settings for the overlay, such as positioning and scroll/close behavior.
314+
* Includes also an optional `Injector` to add to the created dynamic component's injectors.
312315
* @returns Id of the created overlay. Valid until `detach` is called.
313316
*/
314-
public attach(component: Type<any>, settings?: OverlaySettings): string;
317+
public attach(component: Type<any>, settings?: OverlayCreateSettings): string;
318+
// TODO: change third parameter to OverlayCreateSettings and allow passing of Injector and so on.
315319
/**
316320
* Generates an Id. Provide this Id when calling the `show(id)` method
317321
*
318322
* @param component Component Type to show in overlay
319323
* @param viewContainerRef Reference to the container where created component's host view will be inserted
320-
* @param settings Display settings for the overlay, such as positioning and scroll/close behavior.
324+
* @param settings (optional): Display settings for the overlay, such as positioning and scroll/close behavior.
321325
*/
322326
public attach(component: Type<any>, viewContainerRef: ViewContainerRef, settings?: OverlaySettings): string;
323327
public attach(
324328
componentOrElement: ElementRef | Type<any>,
325-
viewContainerRefOrSettings?: ViewContainerRef | OverlaySettings,
326-
moduleRefOrSettings?: OverlaySettings): string {
327-
const info: OverlayInfo = this.getOverlayInfo(componentOrElement, viewContainerRefOrSettings);
329+
viewContainerRefOrSettings?: ViewContainerRef | OverlayCreateSettings,
330+
settings?: OverlaySettings): string {
331+
const info: OverlayInfo = this.getOverlayInfo(componentOrElement, viewContainerRefOrSettings, settings);
328332

329333
if (!info) {
330334
console.warn('Overlay was not able to attach provided component!');
@@ -333,9 +337,8 @@ export class IgxOverlayService implements OnDestroy {
333337

334338
info.id = (this._componentId++).toString();
335339
info.visible = false;
336-
const settings = Object.assign({}, this._defaultSettings, this.getUserOverlaySettings(viewContainerRefOrSettings, moduleRefOrSettings));
337340
// Emit the contentAppending event before appending the content
338-
const eventArgs = { id: info.id, elementRef: info.elementRef, componentRef: info.componentRef, settings };
341+
const eventArgs = { id: info.id, elementRef: info.elementRef, componentRef: info.componentRef, settings: info.settings };
339342
this.contentAppending.emit(eventArgs);
340343
// Append the content to the overlay
341344
info.settings = eventArgs.settings;
@@ -559,29 +562,38 @@ export class IgxOverlayService implements OnDestroy {
559562
}
560563
}
561564

562-
private getUserOverlaySettings(
563-
viewContainerRefOrSettings?: ViewContainerRef | OverlaySettings,
564-
moduleRefOrSettings?: OverlaySettings): OverlaySettings {
565-
let result: OverlaySettings | undefined = moduleRefOrSettings;
566-
if (viewContainerRefOrSettings && !(viewContainerRefOrSettings instanceof ViewContainerRef)) {
567-
result = viewContainerRefOrSettings;
568-
}
569-
return result;
570-
}
571-
565+
/**
566+
* Creates overlayInfo. Sets the info's `elementRef`, `componentRef`and `settings`. Also
567+
* initialize info's `ngZone`, `transformX` and `transformY`.
568+
* @param component ElementRef or Type. If type is provided dynamic component will be created
569+
* @param viewContainerRefOrSettings (optional): If ElementRef is provided for `component` this
570+
* parameter is OverlaySettings. Otherwise it could be ViewContainerRef or OverlayCreateSettings and will be
571+
* used when dynamic component is created.
572+
* @param settings (optional): OverlaySettings when `ViewContainerRef` is provided.
573+
* @returns OverlayInfo
574+
*/
572575
private getOverlayInfo(
573576
component: ElementRef | Type<any>,
574-
viewContainerRefOrSettings?: ViewContainerRef | OverlaySettings): OverlayInfo | null {
577+
viewContainerRefOrSettings?: ViewContainerRef | OverlayCreateSettings,
578+
settings?: OverlaySettings): OverlayInfo | null {
575579
const info: OverlayInfo = { ngZone: this._zone, transformX: 0, transformY: 0 };
580+
let overlaySettings = settings;
576581
if (component instanceof ElementRef) {
577582
info.elementRef = component;
583+
overlaySettings = viewContainerRefOrSettings as OverlaySettings;
578584
} else {
579585
let dynamicComponent: ComponentRef<any>;
580586
if (viewContainerRefOrSettings instanceof ViewContainerRef) {
581-
dynamicComponent = viewContainerRefOrSettings.createComponent(component);
587+
const viewContainerRef = viewContainerRefOrSettings as ViewContainerRef;
588+
dynamicComponent = viewContainerRef.createComponent(component);
582589
} else {
583590
const environmentInjector = this._appRef.injector;
584-
dynamicComponent = createComponent(component, { environmentInjector });
591+
const createSettings = viewContainerRefOrSettings as OverlayCreateSettings | undefined;
592+
let elementInjector: Injector;
593+
if (createSettings) {
594+
({ injector: elementInjector, ...overlaySettings} = createSettings);
595+
}
596+
dynamicComponent = createComponent(component, { environmentInjector, elementInjector });
585597
this._appRef.attachView(dynamicComponent.hostView);
586598
}
587599
if (dynamicComponent.onDestroy) {
@@ -597,6 +609,7 @@ export class IgxOverlayService implements OnDestroy {
597609
info.elementRef = { nativeElement: element };
598610
info.componentRef = dynamicComponent;
599611
}
612+
info.settings = Object.assign({}, this._defaultSettings, overlaySettings);
600613
return info;
601614
}
602615

projects/igniteui-angular/src/lib/services/overlay/utilities.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { AnimationReferenceMetadata } from '@angular/animations';
2-
import { ComponentRef, ElementRef, NgZone } from '@angular/core';
2+
import { ComponentRef, ElementRef, Injector, NgZone } from '@angular/core';
33
import { CancelableBrowserEventArgs, CancelableEventArgs, cloneValue, IBaseEventArgs } from '../../core/utils';
44
import { IgxOverlayOutletDirective } from '../../directives/toggle/toggle.directive';
55
import { AnimationPlayer } from '../animation/animation';
@@ -189,6 +189,13 @@ export interface ConnectedFit {
189189
verticalOffset?: number;
190190
}
191191

192+
export interface OverlayCreateSettings extends OverlaySettings {
193+
/**
194+
* An `Injector` instance to add in the created component ref's injectors tree.
195+
*/
196+
injector?: Injector
197+
}
198+
192199
/** @hidden @internal */
193200
export class Util {
194201
/**

0 commit comments

Comments
 (0)