Skip to content

Commit ddff831

Browse files
esteecodesddinchevahanastasov
authored
feat(IgxOverlayService): add contentAppending emit (#12696)
* feat(IgxOverlayService): add contentAppending event * feat(IgxOverlayService): add contentAppending emit * refactor(Overlay): enhance the emitted args of contentAppending event #12480 * chore(*): update the changelog * test(OverlayService): add few tests for the contentAppending event #12480 --------- Co-authored-by: Desislava Dincheva <[email protected]> Co-authored-by: Hristo <[email protected]> Co-authored-by: ddincheva <[email protected]>
1 parent 25b476a commit ddff831

File tree

5 files changed

+91
-3
lines changed

5 files changed

+91
-3
lines changed

CHANGELOG.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ All notable changes for each version of this project will be documented in this
1717
- `IgxColumnComponent`
1818
- Added `currRec` and `groupRec` parameters to the `groupingComparer` function that give access to the all properties of the compared records.
1919

20+
- `IgxOverlayService`
21+
-A new event `contentAppending` is introduced - the event is emitted before the content is appended to the overlay. The event is emitted with `OverlayEventArgs` arguments and is not cancellable.
22+
2023
### General
2124
- `IgxPivotGrid`
2225
- The `IgxPivotDateDimension` properties `inBaseDimension` and `inOption` have been deprecated and renamed to `baseDimension` and `options` respectively.
@@ -35,9 +38,9 @@ All notable changes for each version of this project will be documented in this
3538
- `igxMask` directive
3639
- Added the capability to escape mask pattern literals.
3740
- `IgxBadge`
38-
- Added `shape` property that controls the shape of the badge and can be either `square` or `rounded`. The default shape of the badge is rounded.
41+
- Added `shape` property that controls the shape of the badge and can be either `square` or `rounded`. The default shape of the badge is rounded.
3942
- `IgxAvatar`
40-
- **Breaking Change** The `roundShape` property has been deprecated and will be removed in a future version. Users can control the shape of the avatar by the newly added `shape` attribute that can be `square`, `rounded` or `circle`. The default shape of the avatar is `square`.
43+
- **Breaking Change** The `roundShape` property has been deprecated and will be removed in a future version. Users can control the shape of the avatar by the newly added `shape` attribute that can be `square`, `rounded` or `circle`. The default shape of the avatar is `square`.
4144
- `IgxOverlayService`
4245
- `attach` method overload accepting `ComponentFactoryResolver` (trough `NgModuleRef`-like object) is now deprecated in line with API deprecated in Angular 13. New overload is added accepting `ViewComponentRef` that should be used instead.
4346

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,5 +134,6 @@ this.overlay.show(component, overlaySettings);
134134
| opened | Emitted after overlay shows | false | |
135135
| closing | Emitted before overlay hides | true | |
136136
| closed | Emitted after overlay hides | false | |
137+
| contentAppending | Emitted before overlay's content is appended | false | |
137138
| contentAppended | Emitted after overlay's content is appended | false | |
138139
| animationStarting | Emitted before animation is started | false | |

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

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
import { fakeAsync, inject, TestBed, tick, waitForAsync } from '@angular/core/testing';
1414
import { BrowserModule } from '@angular/platform-browser';
1515
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
16+
import { first } from 'rxjs/operators';
1617
import { scaleInVerTop, scaleOutVerTop } from '../../animations/main';
1718
import { IgxAvatarComponent, IgxAvatarModule } from '../../avatar/avatar.component';
1819
import { IgxCalendarComponent, IgxCalendarModule } from '../../calendar/public_api';
@@ -558,6 +559,7 @@ describe('igxOverlay', () => {
558559
spyOn(overlayInstance.closed, 'emit');
559560
spyOn(overlayInstance.closing, 'emit');
560561
spyOn(overlayInstance.opened, 'emit');
562+
spyOn(overlayInstance.contentAppending, 'emit');
561563
spyOn(overlayInstance.contentAppended, 'emit');
562564
spyOn(overlayInstance.opening, 'emit');
563565
spyOn(overlayInstance.animationStarting, 'emit');
@@ -571,6 +573,7 @@ describe('igxOverlay', () => {
571573
.toHaveBeenCalledWith({ id: firstCallId, componentRef: jasmine.any(ComponentRef) as any, cancel: false });
572574
const args: OverlayEventArgs = (overlayInstance.opening.emit as jasmine.Spy).calls.mostRecent().args[0];
573575
expect(args.componentRef.instance).toEqual(jasmine.any(SimpleDynamicComponent));
576+
expect(overlayInstance.contentAppending.emit).toHaveBeenCalledTimes(1);
574577
expect(overlayInstance.contentAppended.emit).toHaveBeenCalledTimes(1);
575578
expect(overlayInstance.animationStarting.emit).toHaveBeenCalledTimes(1);
576579

@@ -595,6 +598,7 @@ describe('igxOverlay', () => {
595598
tick();
596599
expect(overlayInstance.opening.emit).toHaveBeenCalledTimes(2);
597600
expect(overlayInstance.opening.emit).toHaveBeenCalledWith({ componentRef: undefined, id: secondCallId, cancel: false });
601+
expect(overlayInstance.contentAppending.emit).toHaveBeenCalledTimes(2);
598602
expect(overlayInstance.contentAppended.emit).toHaveBeenCalledTimes(2);
599603
expect(overlayInstance.animationStarting.emit).toHaveBeenCalledTimes(3);
600604

@@ -616,6 +620,68 @@ describe('igxOverlay', () => {
616620
overlayInstance.detachAll();
617621
}));
618622

623+
it('Should properly emit contentAppending event', fakeAsync(() => {
624+
const fixture = TestBed.createComponent(SimpleRefComponent);
625+
fixture.detectChanges();
626+
const overlayInstance = fixture.componentInstance.overlay;
627+
const os: OverlaySettings = {
628+
excludeFromOutsideClick: [],
629+
positionStrategy: new GlobalPositionStrategy(),
630+
scrollStrategy: new NoOpScrollStrategy(),
631+
modal: true,
632+
closeOnOutsideClick: true,
633+
closeOnEscape: false
634+
};
635+
636+
spyOn(overlayInstance.contentAppending, 'emit');
637+
spyOn(overlayInstance.contentAppended, 'emit');
638+
639+
const firstCallId = overlayInstance.attach(SimpleDynamicComponent);
640+
overlayInstance.show(firstCallId);
641+
tick();
642+
643+
expect(overlayInstance.contentAppending.emit).toHaveBeenCalledTimes(1);
644+
expect(overlayInstance.contentAppended.emit).toHaveBeenCalledTimes(1);
645+
646+
expect(overlayInstance.contentAppending.emit).toHaveBeenCalledWith({ id: firstCallId, elementRef: jasmine.any(Object),
647+
componentRef: jasmine.any(ComponentRef) as any, settings: os })
648+
}));
649+
650+
it('Should properly be able to override OverlaySettings using contentAppending event args', fakeAsync(() => {
651+
const fixture = TestBed.createComponent(SimpleRefComponent);
652+
fixture.detectChanges();
653+
const overlayInstance = fixture.componentInstance.overlay;
654+
const os: OverlaySettings = {
655+
excludeFromOutsideClick: [],
656+
positionStrategy: new GlobalPositionStrategy(),
657+
scrollStrategy: new CloseScrollStrategy(),
658+
modal: false,
659+
closeOnOutsideClick: false,
660+
closeOnEscape: true
661+
};
662+
663+
overlayInstance.contentAppending.pipe(first()).subscribe((e: OverlayEventArgs) => {
664+
// override the default settings
665+
e.settings = os;
666+
});
667+
overlayInstance.contentAppended.pipe(first()).subscribe((e: OverlayEventArgs) => {
668+
const overlay = overlayInstance.getOverlayById(e.id);
669+
expect(overlay.settings.closeOnEscape).toBeTrue();
670+
expect(overlay.settings.modal).toBeFalsy();
671+
expect(overlay.settings.closeOnOutsideClick).toBeFalsy();
672+
});
673+
674+
spyOn(overlayInstance.contentAppended, 'emit').and.callThrough();
675+
spyOn(overlayInstance.contentAppending, 'emit').and.callThrough();
676+
677+
const firstCallId = overlayInstance.attach(SimpleDynamicComponent);
678+
overlayInstance.show(firstCallId);
679+
tick();
680+
681+
expect(overlayInstance.contentAppending.emit).toHaveBeenCalledTimes(1);
682+
expect(overlayInstance.contentAppended.emit).toHaveBeenCalledTimes(1);
683+
}));
684+
619685
it('Should properly set style on position method call - GlobalPosition.', () => {
620686
const mockParent = document.createElement('div');
621687
const mockItem = document.createElement('div');

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,16 @@ export class IgxOverlayService implements OnDestroy {
107107
*/
108108
public closed = new EventEmitter<OverlayEventArgs>();
109109

110+
/**
111+
* Emitted before the content is appended to the overlay.
112+
* ```typescript
113+
* contentAppending(event: OverlayEventArgs){
114+
* const contentAppending = event;
115+
* }
116+
* ```
117+
*/
118+
public contentAppending = new EventEmitter<OverlayEventArgs>();
119+
110120
/**
111121
* Emitted after the content is appended to the overlay, and before animations are started.
112122
* ```typescript
@@ -347,7 +357,11 @@ export class IgxOverlayService implements OnDestroy {
347357
info.id = (this._componentId++).toString();
348358
info.visible = false;
349359
const settings = Object.assign({}, this._defaultSettings, this.getUserOverlaySettings(viewContainerRefOrSettings, moduleRefOrSettings));
350-
info.settings = settings;
360+
// Emit the contentAppending event before appending the content
361+
const eventArgs = { id: info.id, elementRef: info.elementRef, componentRef: info.componentRef, settings };
362+
this.contentAppending.emit(eventArgs);
363+
// Append the content to the overlay
364+
info.settings = eventArgs.settings;
351365
this._overlayInfos.push(info);
352366
info.hook = this.placeElementHook(info.elementRef.nativeElement);
353367
const elementRect = info.elementRef.nativeElement.getBoundingClientRect();

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,10 @@ export interface OverlayEventArgs extends IBaseEventArgs {
111111
id: string;
112112
/** Available when `Type<T>` is provided to the `attach()` method and allows access to the created Component instance */
113113
componentRef?: ComponentRef<any>;
114+
/** Will provide the elementRef of the markup that will be displayed in the overlay */
115+
elementRef?: ElementRef<any>;
116+
/** Will provide the overlay settings which will be used when the component is attached */
117+
settings?: OverlaySettings;
114118
/** Will provide the original keyboard event if closed from ESC or click */
115119
event?: Event;
116120
}

0 commit comments

Comments
 (0)