igniteui-angular-sovn
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
250 lines (225 loc) • 8.4 kB
text/typescript
import { AnimationReferenceMetadata } from '@angular/animations';
import { ComponentRef, ElementRef, NgZone } from '@angular/core';
import { CancelableBrowserEventArgs, CancelableEventArgs, cloneValue, IBaseEventArgs } from '../../core/utils';
import { IgxOverlayOutletDirective } from '../../directives/toggle/toggle.directive';
import { AnimationPlayer } from '../animation/animation';
import { IPositionStrategy } from './position/IPositionStrategy';
import { IScrollStrategy } from './scroll';
export enum HorizontalAlignment {
Left = -1,
Center = -0.5,
Right = 0
}
export enum VerticalAlignment {
Top = -1,
Middle = -0.5,
Bottom = 0
}
/**
* Defines the possible values of the overlays' position strategy.
*/
export enum RelativePositionStrategy {
Connected = 'connected',
Auto = 'auto',
Elastic = 'elastic'
}
/**
* Defines the possible positions for the relative overlay settings presets.
*/
export enum RelativePosition {
Above = 'above',
Below = 'below',
Before = 'before',
After = 'after',
Default = 'default'
}
/**
* Defines the possible positions for the absolute overlay settings presets.
*/
export enum AbsolutePosition {
Bottom = 'bottom',
Top = 'top',
Center = 'center'
}
// TODO: make this interface
export class Point {
constructor(public x: number, public y: number) { }
}
/** @hidden */
export interface OutOfViewPort {
/** Out of view port at Top or Left */
back: number;
/** Out of view port at Bottom or Right */
forward: number;
}
export interface PositionSettings {
/**
* @deprecated in version 10.2.0. Set the target point/element in the overlay settings instead
*
* Attaching target for the component to show
*/
target?: Point | HTMLElement;
/** Direction in which the component should show */
horizontalDirection?: HorizontalAlignment;
/** Direction in which the component should show */
verticalDirection?: VerticalAlignment;
/** Target's starting point */
horizontalStartPoint?: HorizontalAlignment;
/** Target's starting point */
verticalStartPoint?: VerticalAlignment;
/** Animation applied while overlay opens */
openAnimation?: AnimationReferenceMetadata;
/** Animation applied while overlay closes */
closeAnimation?: AnimationReferenceMetadata;
/** The size up to which element may shrink when shown in elastic position strategy */
minSize?: Size;
}
export interface OverlaySettings {
/** Attaching target for the component to show */
target?: Point | HTMLElement;
/** Position strategy to use with these settings */
positionStrategy?: IPositionStrategy;
/** Scroll strategy to use with these settings */
scrollStrategy?: IScrollStrategy;
/** Set if the overlay should be in modal mode */
modal?: boolean;
/** Set if the overlay should close on outside click */
closeOnOutsideClick?: boolean;
/** Set if the overlay should close when `Esc` key is pressed */
closeOnEscape?: boolean;
/** Set the outlet container to attach the overlay to */
outlet?: IgxOverlayOutletDirective | ElementRef;
/**
* @hidden @internal
* Elements to be excluded for closeOnOutsideClick.
* Clicking on the elements in this collection will not close the overlay when closeOnOutsideClick = true.
*/
excludeFromOutsideClick?: HTMLElement[];
}
export interface OverlayEventArgs extends IBaseEventArgs {
/** Id of the overlay generated with `attach()` method */
id: string;
/** Available when `Type<T>` is provided to the `attach()` method and allows access to the created Component instance */
componentRef?: ComponentRef<any>;
/** Will provide the elementRef of the markup that will be displayed in the overlay */
elementRef?: ElementRef<any>;
/** Will provide the overlay settings which will be used when the component is attached */
settings?: OverlaySettings;
/** Will provide the original keyboard event if closed from ESC or click */
event?: Event;
}
export interface OverlayCancelableEventArgs extends OverlayEventArgs, CancelableEventArgs {
}
export interface OverlayClosingEventArgs extends OverlayEventArgs, CancelableBrowserEventArgs {
}
export interface OverlayAnimationEventArgs extends IBaseEventArgs {
/** Id of the overlay generated with `attach()` method */
id: string;
/** Animation player that will play the animation */
animationPlayer: AnimationPlayer;
/** Type of animation to be played. It should be either 'open' or 'close' */
animationType: 'open' | 'close';
}
export interface Size {
/** Gets or sets the horizontal component of Size */
width: number;
/** Gets or sets the vertical component of Size */
height: number;
}
/** @hidden */
export interface OverlayInfo {
id?: string;
visible?: boolean;
detached?: boolean;
elementRef?: ElementRef;
componentRef?: ComponentRef<any>;
settings?: OverlaySettings;
initialSize?: Size;
hook?: HTMLElement;
openAnimationPlayer?: AnimationPlayer;
// calling animation.destroy in detach fires animation.done. This should not happen
// this is why we should trace if animation ever started
openAnimationDetaching?: boolean;
closeAnimationPlayer?: AnimationPlayer;
// calling animation.destroy in detach fires animation.done. This should not happen
// this is why we should trace if animation ever started
closeAnimationDetaching?: boolean;
ngZone: NgZone;
transformX?: number;
transformY?: number;
event?: Event;
wrapperElement?: HTMLElement;
}
/** @hidden */
export interface ConnectedFit {
contentElementRect?: Partial<DOMRect>;
targetRect?: Partial<DOMRect>;
viewPortRect?: Partial<DOMRect>;
fitHorizontal?: OutOfViewPort;
fitVertical?: OutOfViewPort;
left?: number;
right?: number;
top?: number;
bottom?: number;
horizontalOffset?: number;
verticalOffset?: number;
}
/** @hidden @internal */
export class Util {
/**
* Calculates the rectangle of target for provided overlay settings. Defaults to 0,0,0,0,0,0 rectangle
* if no target is provided
*
* @param settings Overlay settings for which to calculate target rectangle
*/
public static getTargetRect(target?: Point | HTMLElement): Partial<DOMRect> {
let targetRect: Partial<DOMRect> = {
bottom: 0,
height: 0,
left: 0,
right: 0,
top: 0,
width: 0
};
if (target instanceof HTMLElement) {
targetRect = (target as HTMLElement).getBoundingClientRect();
} else if (target instanceof Point) {
const targetPoint = target as Point;
targetRect = {
bottom: targetPoint.y,
height: 0,
left: targetPoint.x,
right: targetPoint.x,
top: targetPoint.y,
width: 0
};
}
return targetRect;
}
public static getViewportRect(document: Document): Partial<DOMRect> {
const width = document.documentElement.clientWidth;
const height = document.documentElement.clientHeight;
const scrollPosition = Util.getViewportScrollPosition(document);
return {
top: scrollPosition.y,
left: scrollPosition.x,
right: scrollPosition.x + width,
bottom: scrollPosition.y + height,
width,
height,
};
}
public static getViewportScrollPosition(document: Document): Point {
const documentElement = document.documentElement;
const documentRect = documentElement.getBoundingClientRect();
const horizontalScrollPosition =
-documentRect.left || document.body.scrollLeft || window.scrollX || documentElement.scrollLeft || 0;
const verticalScrollPosition = -documentRect.top || document.body.scrollTop || window.scrollY || documentElement.scrollTop || 0;
return new Point(horizontalScrollPosition, verticalScrollPosition);
}
public static cloneInstance(object) {
const clonedObj = Object.assign(Object.create(Object.getPrototypeOf(object)), object);
clonedObj.settings = cloneValue(clonedObj.settings);
return clonedObj;
}
}