Skip to content

Commit ff5390a

Browse files
committed
feat(overlay): move target to overlaySettings #7807
1 parent 8bf3045 commit ff5390a

12 files changed

+520
-26
lines changed

projects/igniteui-angular/src/lib/grids/grid.common.ts

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Directive } from '@angular/core';
22
import { ConnectedPositioningStrategy } from '../services/public_api';
3-
import { VerticalAlignment, PositionSettings } from '../services/overlay/utilities';
3+
import { VerticalAlignment, PositionSettings, Point } from '../services/overlay/utilities';
44
import { scaleInVerBottom, scaleInVerTop } from '../animations/main';
55
import { IgxForOfSyncService } from '../directives/for-of/for_of.sync.service';
66
import { ColumnPinningPosition, RowPinningPosition } from './common/enums';
@@ -35,9 +35,10 @@ export class RowEditPositionStrategy extends ConnectedPositioningStrategy {
3535
isTop = false;
3636
isTopInitialPosition = null;
3737
public settings: RowEditPositionSettings;
38-
position(contentElement: HTMLElement, size: { width: number, height: number }, document?: Document, initialCall?: boolean): void {
38+
position(contentElement: HTMLElement, size: { width: number, height: number }, document?: Document, initialCall?: boolean,
39+
target?: Point | HTMLElement): void {
3940
const container = this.settings.container; // grid.tbody
40-
const target = <HTMLElement>this.settings.target; // current grid.row
41+
const targetElement = target ? <HTMLElement>target : <HTMLElement>this.settings.target; // current grid.row
4142

4243
// Position of the overlay depends on the available space in the grid.
4344
// If the bottom space is not enough then the the row overlay will show at the top of the row.
@@ -46,13 +47,13 @@ export class RowEditPositionStrategy extends ConnectedPositioningStrategy {
4647
this.isTop = this.isTopInitialPosition !== null ?
4748
this.isTopInitialPosition :
4849
container.getBoundingClientRect().bottom <
49-
target.getBoundingClientRect().bottom + contentElement.getBoundingClientRect().height;
50+
targetElement.getBoundingClientRect().bottom + contentElement.getBoundingClientRect().height;
5051

5152
// Set width of the row editing overlay to equal row width, otherwise it fits 100% of the grid.
52-
contentElement.style.width = target.clientWidth + 'px';
53+
contentElement.style.width = targetElement.clientWidth + 'px';
5354
this.settings.verticalStartPoint = this.settings.verticalDirection = this.isTop ? VerticalAlignment.Top : VerticalAlignment.Bottom;
5455
this.settings.openAnimation = this.isTop ? scaleInVerBottom : scaleInVerTop;
5556

56-
super.position(contentElement, { width: target.clientWidth, height: target.clientHeight }, document, initialCall);
57+
super.position(contentElement, { width: targetElement.clientWidth, height: targetElement.clientHeight }, document, initialCall);
5758
}
5859
}

projects/igniteui-angular/src/lib/select/select-positioning-strategy.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { VerticalAlignment, HorizontalAlignment, PositionSettings, Size, Util, ConnectedFit } from '../services/overlay/utilities';
1+
import { VerticalAlignment, HorizontalAlignment, PositionSettings, Size, Util, ConnectedFit, Point } from '../services/overlay/utilities';
22
import { IPositionStrategy } from '../services/overlay/position';
33
import { fadeOut, fadeIn } from '../animations/main';
44
import { IgxSelectBase } from './select.common';
@@ -31,9 +31,10 @@ export class SelectPositioningStrategy extends BaseFitPositionStrategy implement
3131
private global_styles: SelectStyles = {};
3232

3333
/** @inheritdoc */
34-
position(contentElement: HTMLElement, size: Size, document?: Document, initialCall?: boolean): void {
34+
position(contentElement: HTMLElement, size: Size, document?: Document, initialCall?: boolean, target?: Point | HTMLElement): void {
3535
this.select.scrollContainer.scrollTop = 0;
36-
const rects = super.calculateElementRectangles(contentElement);
36+
const targetElement = target ? target : this.settings.target;
37+
const rects = super.calculateElementRectangles(contentElement, targetElement);
3738
// selectFit obj, to be used for both cases of initialCall and !initialCall(page scroll/overlay repositionAll)
3839
const selectFit: SelectFit = {
3940
verticalOffset: this.global_yOffset,

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

+4-2
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,8 @@ export class IgxOverlayService implements OnDestroy {
250250
height: contentElementRect.height
251251
},
252252
this._document,
253-
false);
253+
false,
254+
overlayInfo.settings.target);
254255
}
255256

256257
/**
@@ -312,7 +313,8 @@ export class IgxOverlayService implements OnDestroy {
312313
info.elementRef.nativeElement.parentElement,
313314
{ width: info.initialSize.width, height: info.initialSize.height },
314315
document,
315-
true);
316+
true,
317+
info.settings.target);
316318
info.settings.scrollStrategy.initialize(this._document, this, info.id);
317319
info.settings.scrollStrategy.attach();
318320
}

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

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { PositionSettings, Size } from './../utilities';
1+
import { PositionSettings, Size, Point } from './../utilities';
22

33
/**
44
* [Documentation](https://www.infragistics.com/products/ignite-ui-angular/angular/components/overlay_position.html)
@@ -16,11 +16,12 @@ export interface IPositionStrategy {
1616
* @param size Size of the element
1717
* @param document reference to the Document object
1818
* @param initialCall should be true if this is the initial call to the method
19+
* @param target attaching target for the component to show
1920
* ```typescript
2021
* settings.positionStrategy.position(content, size, document, true);
2122
* ```
2223
*/
23-
position(contentElement: HTMLElement, size?: Size, document?: Document, initialCall?: boolean): void;
24+
position(contentElement: HTMLElement, size?: Size, document?: Document, initialCall?: boolean, target?: Point | HTMLElement): void;
2425

2526
/**
2627
* Clone the strategy instance.

projects/igniteui-angular/src/lib/services/overlay/position/base-fit-position-strategy.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import { ConnectedPositioningStrategy } from './connected-positioning-strategy';
2-
import { HorizontalAlignment, VerticalAlignment, PositionSettings, Size, Util, ConnectedFit, OutOfViewPort } from '../utilities';
2+
import { HorizontalAlignment, VerticalAlignment, PositionSettings, Size, Util, ConnectedFit, OutOfViewPort, Point } from '../utilities';
33

44
export abstract class BaseFitPositionStrategy extends ConnectedPositioningStrategy {
55
protected _initialSize: Size;
66
protected _initialSettings: PositionSettings;
77

88
/** @inheritdoc */
9-
position(contentElement: HTMLElement, size: Size, document?: Document, initialCall?: boolean): void {
10-
const rects = super.calculateElementRectangles(contentElement);
9+
position(contentElement: HTMLElement, size: Size, document?: Document, initialCall?: boolean, target?: Point | HTMLElement): void {
10+
const targetElement = target ? target : this.settings.target;
11+
const rects = super.calculateElementRectangles(contentElement, targetElement);
1112
const connectedFit: ConnectedFit = {};
1213
if (initialCall) {
1314
connectedFit.targetRect = rects.targetRect;

projects/igniteui-angular/src/lib/services/overlay/position/connected-positioning-strategy.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,17 @@ export class ConnectedPositioningStrategy implements IPositionStrategy {
3838
* Obtains the ClientRect objects for the required elements - target and element to position
3939
* @returns target and element ClientRect objects
4040
*/
41-
protected calculateElementRectangles(contentElement): { targetRect: ClientRect, elementRect: ClientRect } {
41+
protected calculateElementRectangles(contentElement, target: Point | HTMLElement): { targetRect: ClientRect, elementRect: ClientRect } {
4242
return {
43-
targetRect: Util.getTargetRect(this.settings),
43+
targetRect: Util.getTargetRect(target),
4444
elementRect: contentElement.getBoundingClientRect() as ClientRect
4545
};
4646
}
4747

4848
/** @inheritdoc */
49-
position(contentElement: HTMLElement, size: Size, document?: Document, initialCall?: boolean): void {
50-
const rects = this.calculateElementRectangles(contentElement);
49+
position(contentElement: HTMLElement, size: Size, document?: Document, initialCall?: boolean, target?: Point | HTMLElement): void {
50+
const targetElement = target ? target : this.settings.target;
51+
const rects = this.calculateElementRectangles(contentElement, targetElement);
5152
this.setStyle(contentElement, rects.targetRect, rects.elementRect, {});
5253
}
5354

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

+11-6
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ export interface OutOfViewPort {
3131
}
3232

3333
export interface PositionSettings {
34-
/** Attaching target for the component to show */
34+
/**
35+
* @deprecated Set the target point/element in the overlay instead.
36+
* Attaching target for the component to show
37+
*/
3538
target?: Point | HTMLElement;
3639
/** Direction in which the component should show */
3740
horizontalDirection?: HorizontalAlignment;
@@ -50,6 +53,8 @@ export interface PositionSettings {
5053
}
5154

5255
export interface OverlaySettings {
56+
/** Attaching target for the component to show */
57+
target?: Point | HTMLElement;
5358
/** Position strategy to use with these settings */
5459
positionStrategy?: IPositionStrategy;
5560
/** Scroll strategy to use with these settings */
@@ -139,7 +144,7 @@ export class Util {
139144
* if no target is provided
140145
* @param settings Overlay settings for which to calculate target rectangle
141146
*/
142-
static getTargetRect(settings: PositionSettings): ClientRect {
147+
static getTargetRect(target?: Point | HTMLElement): ClientRect {
143148
let targetRect: ClientRect = {
144149
bottom: 0,
145150
height: 0,
@@ -149,10 +154,10 @@ export class Util {
149154
width: 0
150155
};
151156

152-
if (settings.target instanceof HTMLElement) {
153-
targetRect = (settings.target as HTMLElement).getBoundingClientRect();
154-
} else if (settings.target instanceof Point) {
155-
const targetPoint = settings.target as Point;
157+
if (target instanceof HTMLElement) {
158+
targetRect = (target as HTMLElement).getBoundingClientRect();
159+
} else if (target instanceof Point) {
160+
const targetPoint = target as Point;
156161
targetRect = {
157162
bottom: targetPoint.y,
158163
height: 0,

src/app/app.component.ts

+5
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,11 @@ export class AppComponent implements OnInit {
348348
icon: 'flip_to_front',
349349
name: 'Overlay'
350350
},
351+
{
352+
link: '/overlay-target',
353+
icon: 'flip_to_front',
354+
name: 'Overlay With Target'
355+
},
351356
{
352357
link: '/overlay-animation',
353358
icon: 'flip_to_front',

src/app/app.module.ts

+2
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ import { DisplayDensityDropDownComponent } from './drop-down/display-density/dis
8585
import { DropDownVirtualComponent } from './drop-down/drop-down-virtual/drop-down-virtual.component';
8686
import { ComboSampleComponent } from './combo/combo.sample';
8787
import { OverlaySampleComponent } from './overlay/overlay.sample';
88+
import { OverlayTargetSampleComponent } from './overlay/overlay-target.sample';
8889
import { OverlayAnimationSampleComponent } from './overlay/overlay-animation.sample';
8990
import { RadioSampleComponent } from './radio/radio.sample';
9091
import { TooltipSampleComponent } from './tooltip/tooltip.sample';
@@ -167,6 +168,7 @@ const components = [
167168
NavbarSampleComponent,
168169
NavdrawerSampleComponent,
169170
OverlaySampleComponent,
171+
OverlayTargetSampleComponent,
170172
OverlayAnimationSampleComponent,
171173
PageHeaderComponent,
172174
ProgressbarSampleComponent,
+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<div #container class="sample-wrapper">
2+
<app-page-header title="Overlay" description="description for overlay"></app-page-header>
3+
<section class="sample-content">
4+
<div class="column">
5+
<p>Directions</p>
6+
<div class="direction-container">
7+
<div id="tld" class="direction" (click)="setDirection($event)"></div>
8+
<div id="tcd" class="direction" (click)="setDirection($event)"></div>
9+
<div id="trd" class="direction" (click)="setDirection($event)"></div>
10+
</div>
11+
<div class="direction-container">
12+
<div id="mld" class="direction" (click)="setDirection($event)"></div>
13+
<div id="mcd" class="direction selected" (click)="setDirection($event)"></div>
14+
<div id="mrd" class="direction" (click)="setDirection($event)"></div>
15+
</div>
16+
<div class="direction-container">
17+
<div id="bld" class="direction" (click)="setDirection($event)"></div>
18+
<div id="bcd" class="direction" (click)="setDirection($event)"></div>
19+
<div id="brd" class="direction" (click)="setDirection($event)"></div>
20+
</div>
21+
<p>Starting Point</p>
22+
<div class="start-point-container">
23+
<div id="tlsp" class="start-point" (click)="setStartPoint($event)"></div>
24+
<div id="tcsp" class="start-point" (click)="setStartPoint($event)"></div>
25+
<div id="trsp" class="start-point" (click)="setStartPoint($event)"></div>
26+
</div>
27+
<div class="start-point-container">
28+
<div id="mlsp" class="start-point" (click)="setStartPoint($event)"></div>
29+
<div id="mcsp" class="start-point selected" (click)="setStartPoint($event)"></div>
30+
<div id="mrsp" class="start-point" (click)="setStartPoint($event)"></div>
31+
</div>
32+
<div class="start-point-container">
33+
<div id="blsp" class="start-point" (click)="setStartPoint($event)"></div>
34+
<div id="bcsp" class="start-point" (click)="setStartPoint($event)"></div>
35+
<div id="brsp" class="start-point" (click)="setStartPoint($event)"></div>
36+
</div>
37+
</div>
38+
<div class="column">
39+
<p>Strategies</p>
40+
<div class="radio-group">
41+
<p>Position Strategies</p>
42+
<igx-radio *ngFor="let item of positionStrategies" value="{{item}}" name="ps"
43+
[(ngModel)]="positionStrategy" (change)="onChange($event)">{{item}}</igx-radio>
44+
</div>
45+
<div class="radio-group">
46+
<p>Scroll Strategies</p>
47+
<igx-radio *ngFor="let item of scrollStrategies" value="{{item}}" name="ss" [(ngModel)]="scrollStrategy"
48+
(change)="onChange($event)">{{item}}</igx-radio>
49+
</div>
50+
</div>
51+
<div class="column">
52+
<p>Settings</p>
53+
<div>
54+
<igx-switch class="settings" [(ngModel)]="closeOnOutsideClick" name="close"
55+
[value]="closeOnOutsideClick" (change)="onSwitchChange($event)">Close On Outside Click</igx-switch>
56+
</div>
57+
<div>
58+
<igx-switch class="settings" [(ngModel)]="modal" name="modal" [value]="modal"
59+
(change)="onSwitchChange($event)">Modal</igx-switch>
60+
</div>
61+
<div>
62+
<igx-switch class="settings" [(ngModel)]="useOutlet" name="outlet" [value]="useOutlet"
63+
(change)="onSwitchChange($event)">Open in outlet</igx-switch>
64+
</div>
65+
<div>
66+
<igx-input-group>
67+
<input igxInput name="dropDownItems" type="number" [(ngModel)]="itemsCount">
68+
<label igxLabel for="dropDownItems">Drop down items</label>
69+
</igx-input-group>
70+
<igx-input-group>
71+
<input igxInput name="dropDownWidth" type="number" [(ngModel)]="dropDownWidth">
72+
<label igxLabel for="dropDownWidth">Drop down width</label>
73+
</igx-input-group>
74+
</div>
75+
</div>
76+
<div #outlet class="outlet column">
77+
Outlet
78+
</div>
79+
<button #button igxButton="raised" igxRipple igxDrag (click)="toggleDropDown()" [style.position]="'absolute'"
80+
(dragEnd)="onDragEnd($event)" (dragStart)="onDragStart($event)">Toggle</button>
81+
<igx-drop-down width="{{dropDownWidth}}px">
82+
<igx-drop-down-item *ngFor="let item of items">
83+
<div class="igx-drop-down__item-template">
84+
{{ item }}
85+
</div>
86+
</igx-drop-down-item>
87+
</igx-drop-down>
88+
</section>
89+
</div>

0 commit comments

Comments
 (0)