diff --git a/projects/igniteui-angular/src/lib/drop-down/drop-down.base.ts b/projects/igniteui-angular/src/lib/drop-down/drop-down.base.ts index 4eae00d0b80..0247e8860af 100644 --- a/projects/igniteui-angular/src/lib/drop-down/drop-down.base.ts +++ b/projects/igniteui-angular/src/lib/drop-down/drop-down.base.ts @@ -3,7 +3,7 @@ import { QueryList, ViewChild, Output, EventEmitter, ChangeDetectorRef } from '@angular/core'; -import { CancelableEventArgs } from '../core/utils'; +import { CancelableEventArgs, isIE } from '../core/utils'; import { IgxSelectionAPIService } from '../core/selection'; import { OverlaySettings } from '../services'; import { IToggleView } from '../core/navigation'; @@ -461,7 +461,18 @@ export abstract class IgxDropDownBase implements OnInit, IToggleView { */ protected scrollToItem(item: IgxDropDownItemBase) { const itemPosition = this.calculateScrollPosition(item); - this.scrollContainer.scrollTop = (itemPosition); + + // in IE11 setting sctrollTop is somehow slow and forces dropdown + // to appear on screen before animation start. As a result dropdown + // flickers badly. This is why we set scrollTop just a little later + // allowing animation to start and prevent dropdown flickering + if (isIE()) { + setTimeout(() => { + this.scrollContainer.scrollTop = (itemPosition); + }, 1); + } else { + this.scrollContainer.scrollTop = (itemPosition); + } } protected scrollToHiddenItem(newItem: IgxDropDownItemBase) { diff --git a/projects/igniteui-angular/src/lib/services/overlay/overlay.ts b/projects/igniteui-angular/src/lib/services/overlay/overlay.ts index 298f2abcc51..7198185eaf8 100644 --- a/projects/igniteui-angular/src/lib/services/overlay/overlay.ts +++ b/projects/igniteui-angular/src/lib/services/overlay/overlay.ts @@ -20,6 +20,7 @@ import { AnimationBuilder, AnimationReferenceMetadata, AnimationMetadataType, An import { fromEvent, Subject } from 'rxjs'; import { take, filter, takeUntil } from 'rxjs/operators'; import { IAnimationParams } from '../../animations/main'; +import { ElasticPositionStrategy } from './position'; /** * [Documentation](https://www.infragistics.com/products/ignite-ui-angular/angular/components/overlay_main.html) @@ -166,7 +167,10 @@ export class IgxOverlayService implements OnDestroy { this.updateSize(info); this._overlayInfos.push(info); - info.originalElementStyle = info.elementRef.nativeElement.style; + const elementStyle = info.elementRef.nativeElement.style; + if (settings.positionStrategy instanceof ElasticPositionStrategy) { + info.originalElementStyleSize = { width: elementStyle.width, height: elementStyle.height }; + } settings.positionStrategy.position( info.elementRef.nativeElement.parentElement, { width: info.initialSize.width, height: info.initialSize.height }, @@ -260,7 +264,10 @@ export class IgxOverlayService implements OnDestroy { overlayInfo.settings.positionStrategy.position( overlayInfo.elementRef.nativeElement.parentElement, - { width: overlayInfo.initialSize.width, height: overlayInfo.initialSize.height }, + { + width: overlayInfo.elementRef.nativeElement.parentElement.clientWidth, + height: overlayInfo.elementRef.nativeElement.parentElement.clientHeight + }, this._document, false, overlayInfo.settings.positionStrategy.settings.minSize); @@ -403,7 +410,13 @@ export class IgxOverlayService implements OnDestroy { this._overlayElement.parentElement.removeChild(this._overlayElement); this._overlayElement = null; } - info.elementRef.nativeElement.style = info.originalElementStyle; + + // restore the element's original width and height if any + if (info.originalElementStyleSize) { + info.elementRef.nativeElement.style.height = info.originalElementStyleSize.height; + info.elementRef.nativeElement.style.width = info.originalElementStyleSize.width; + } + this.onClosed.emit({ id: info.id, componentRef: info.componentRef }); } diff --git a/projects/igniteui-angular/src/lib/services/overlay/position/elastic-position-strategy.ts b/projects/igniteui-angular/src/lib/services/overlay/position/elastic-position-strategy.ts index d598b3aa881..f8c58fba6ba 100644 --- a/projects/igniteui-angular/src/lib/services/overlay/position/elastic-position-strategy.ts +++ b/projects/igniteui-angular/src/lib/services/overlay/position/elastic-position-strategy.ts @@ -4,50 +4,52 @@ import { Size, HorizontalAlignment, VerticalAlignment, PositionSettings } from ' export class ElasticPositionStrategy extends BaseFitPositionStrategy implements IPositionStrategy { fitHorizontal(element: HTMLElement, settings: PositionSettings, innerRect: ClientRect, outerRect: ClientRect, minSize: Size) { + let extend = 0; switch (settings.horizontalDirection) { case HorizontalAlignment.Left: { - let extend = outerRect.left - innerRect.left; + extend = outerRect.left - innerRect.left; if (extend > innerRect.width - minSize.width) { extend = innerRect.width - minSize.width; } const translateX = `translateX(${innerRect.left + extend}px)`; element.style.transform = element.style.transform.replace(/translateX\([.-\d]+px\)/g, translateX); - (element.firstChild).style.width = `${innerRect.width - extend}px`; break; } case HorizontalAlignment.Right: { - let extend = innerRect.right - outerRect.right; + extend = innerRect.right - outerRect.right; if (extend > innerRect.width - minSize.width) { extend = innerRect.width - minSize.width; } - - (element.firstChild).style.width = `${innerRect.width - extend}px`; break; } } + + element.style.width = `${innerRect.width - extend}px`; + (element.firstChild).style.width = `${innerRect.width - extend}px`; } fitVertical(element: HTMLElement, settings: PositionSettings, innerRect: ClientRect, outerRect: ClientRect, minSize: Size) { + let extend = 0; switch (settings.verticalDirection) { case VerticalAlignment.Top: { - let extend = outerRect.top - innerRect.top; + extend = outerRect.top - innerRect.top; if (extend > innerRect.height - minSize.height) { extend = innerRect.height - minSize.height; } const translateY = `translateY(${innerRect.top + extend}px)`; element.style.transform = element.style.transform.replace(/translateY\([.-\d]+px\)/g, translateY); - (element.firstChild).style.height = `${innerRect.width - extend}px`; break; } case VerticalAlignment.Bottom: { - let extend = innerRect.bottom - outerRect.bottom; + extend = innerRect.bottom - outerRect.bottom; if (extend > innerRect.height - minSize.height) { extend = innerRect.height - minSize.height; } - - (element.firstChild).style.height = `${innerRect.height - extend}px`; break; } } + + element.style.height = `${innerRect.height - extend}px`; + (element.firstChild).style.height = `${innerRect.height - extend}px`; } } diff --git a/projects/igniteui-angular/src/lib/services/overlay/utilities.ts b/projects/igniteui-angular/src/lib/services/overlay/utilities.ts index 1cdab04f92b..d37e15c156b 100644 --- a/projects/igniteui-angular/src/lib/services/overlay/utilities.ts +++ b/projects/igniteui-angular/src/lib/services/overlay/utilities.ts @@ -117,5 +117,5 @@ export interface OverlayInfo { closeAnimationPlayer?: AnimationPlayer; openAnimationInnerPlayer?: any; closeAnimationInnerPlayer?: any; - originalElementStyle?: string; + originalElementStyleSize?: Size; } diff --git a/src/app/overlay/overlay.sample.html b/src/app/overlay/overlay.sample.html index 57b558c1bcf..a2391bf343d 100644 --- a/src/app/overlay/overlay.sample.html +++ b/src/app/overlay/overlay.sample.html @@ -61,7 +61,7 @@ - +
{{ item }} diff --git a/src/app/overlay/overlay.sample.ts b/src/app/overlay/overlay.sample.ts index 3e95037c2cf..7b378bf702e 100644 --- a/src/app/overlay/overlay.sample.ts +++ b/src/app/overlay/overlay.sample.ts @@ -27,13 +27,13 @@ export class OverlaySampleComponent { modal: true, closeOnOutsideClick: true }; - items = [ - 'Item 1', - 'Item 2', - 'Item 3', - 'Item 4', - 'Item 5' - ]; + constructor() { + for (let item = 0; item < 100; item++) { + this.items.push(`Item ${item}`); + } + } + + items = []; buttonLeft = 90; buttonTop = 35;