From c990b871f59be3ee7d1435bb5a804d582d982ba5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=87etin?= <69278826+cetincakiroglu@users.noreply.github.com> Date: Tue, 18 Oct 2022 11:25:37 +0300 Subject: [PATCH] refactor --- src/app/components/dropdown/dropdown.ts | 135 ++++++++--------- src/app/components/overlay/overlay.css | 19 ++- src/app/components/overlay/overlay.ts | 189 +++++++++++++----------- 3 files changed, 182 insertions(+), 161 deletions(-) diff --git a/src/app/components/dropdown/dropdown.ts b/src/app/components/dropdown/dropdown.ts index c4209c2b8ca..8f252f24fc8 100755 --- a/src/app/components/dropdown/dropdown.ts +++ b/src/app/components/dropdown/dropdown.ts @@ -87,83 +87,79 @@ export class DropdownItem {
- - -
- - - - -
- - -
-
-
-
- - - + +
+ +
+ + + + +
+ + +
- - - +
+
+ + + - - - - - - - -
    - - -
  • - {{getOptionGroupLabel(optgroup)||'empty'}} - -
  • - + + + - - - - - - - - -
  • - - {{emptyFilterMessageLabel}} + + + + + + +
      + + +
    • + {{getOptionGroupLabel(optgroup)||'empty'}} + +
    • + +
      - - -
    • - - {{emptyMessageLabel}} + + - -
    • -
    -
    + + + + + +
  • + + {{emptyFilterMessageLabel}} + + +
  • +
  • + + {{emptyMessageLabel}} + + +
  • +
+
+
+
-
`, - animations: [ - trigger('overlayAnimation', [ - transition(':enter, :leave', [ - query('@*', animateChild(), {optional: true}) - ]) - ]) - ], + host: { 'class': 'p-element p-inputwrapper', '[class.p-inputwrapper-filled]': 'filled', @@ -722,13 +718,12 @@ export class Dropdown implements OnInit,AfterViewInit,AfterContentInit,AfterView } onOverlayAnimationStart(event: AnimationEvent) { - if (event.toState === null && event.fromState === 'void') { + if (event.toState === 'visible') { this.itemsWrapper = DomHandler.findSingle(this.overlayViewChild.el.nativeElement, this.virtualScroll ? '.p-scroller' : '.p-dropdown-items-wrapper'); this.virtualScroll && this.scroller.setContentEl(this.itemsViewChild.nativeElement); this.overlayViewChild.appendOverlay(); this.overlayViewChild.alignOverlay(); this.bindDocumentClickListener(); - this.bindDocumentResizeListener(); this.bindScrollListener(); if (this.options && this.options.length) { @@ -757,7 +752,7 @@ export class Dropdown implements OnInit,AfterViewInit,AfterContentInit,AfterView this.onShow.emit(event); } - if (event.toState === 'void' && event.fromState === null) { + if (event.toState === 'void') { this.onOverlayHide(); this.onHide.emit(event); } diff --git a/src/app/components/overlay/overlay.css b/src/app/components/overlay/overlay.css index 11ab7a7e6c9..a7fc4f67c0d 100644 --- a/src/app/components/overlay/overlay.css +++ b/src/app/components/overlay/overlay.css @@ -1,11 +1,12 @@ .p-overlay-mask { - display: flex; - justify-content: center; position: fixed; top: 0; left: 0; width: 100%; height: 100%; + display: flex; + justify-content: center; + align-items: center; } .p-overlay-responsive { @@ -16,13 +17,21 @@ } .p-overlay-panel-start { - align-self: flex-start; + align-items: flex-start; } .p-overlay-panel-center { - align-self: center; + align-items: center; } .p-overlay-panel-end { - align-self: flex-end; + align-items: flex-end; +} + +.p-overlay { + position: absolute; +} + +.p-overlay-panel-static { + position: static; } \ No newline at end of file diff --git a/src/app/components/overlay/overlay.ts b/src/app/components/overlay/overlay.ts index c26f2f2bfae..df3ffb421a7 100644 --- a/src/app/components/overlay/overlay.ts +++ b/src/app/components/overlay/overlay.ts @@ -1,4 +1,4 @@ -import {NgModule,Component,Input,OnDestroy,Renderer2,ElementRef,ChangeDetectionStrategy, ViewEncapsulation, ViewChild, Inject} from '@angular/core'; +import {NgModule,Component,Input,OnDestroy,Renderer2,ElementRef,ChangeDetectionStrategy, ViewEncapsulation, ViewChild, Inject, Output, EventEmitter, ChangeDetectorRef} from '@angular/core'; import {CommonModule, DOCUMENT} from '@angular/common'; import {DomHandler} from 'primeng/dom'; import {SharedModule, PrimeNGConfig, OverlayService} from 'primeng/api'; @@ -7,7 +7,7 @@ import {trigger,style,transition,animate, animation, useAnimation} from '@angula import {ZIndexUtils} from 'primeng/utils'; const showAnimation = animation([ - style({ transform: '{{transform}}', opacity: 1 }), + style({ transform: '{{transform}}', opacity: 0 }), animate('{{showTransitionParams}}') ]); @@ -18,17 +18,20 @@ const hideAnimation = animation([ @Component({ selector: 'p-overlay', template: ` -
- +
+
+
+ +
+
- `, animations: [ trigger('overlayAnimation', [ - transition('void => visible', [ + transition(':enter', [ useAnimation(showAnimation) ]), - transition('visible => void', [ + transition(':leave', [ useAnimation(hideAnimation) ]) ]) @@ -37,8 +40,7 @@ const hideAnimation = animation([ encapsulation: ViewEncapsulation.None, styleUrls: ['./overlay.css'], host: { - 'class': 'p-element', - '[class.p-overlay-panel]': 'true' + 'class': 'p-element' } }) export class Overlay implements OnDestroy { @@ -48,27 +50,27 @@ export class Overlay implements OnDestroy { @Input() showTransitionOptions: string = '.12s cubic-bezier(0, 0, 0.2, 1)'; @Input() hideTransitionOptions: string = '.1s linear'; - - @Input() panelClass: string; - - @Input() panelStyleClass: string; - - @Input() overlayAnimation: string; @Input() container: ElementRef; @Input() autoZIndex: boolean; - @Input() panelStyle: string; - - get overlayDirection(): string { - return this._overlayDirection; - } + @Output() onAnimationStart: EventEmitter = new EventEmitter(); + + @Output() onAnimationEnd: EventEmitter = new EventEmitter(); + + @Output() onOverlayHide: EventEmitter = new EventEmitter(); + + @ViewChild('overlay') overlayViewChild: ElementRef; + + @ViewChild('content') contentViewChild: ElementRef; + + @ViewChild('mask') maskViewChild: ElementRef; @Input() set overlayDirection(value: string) { - const viewport = DomHandler.getViewport(); - if (value && viewport.width < this.overlayBreakpoints) { + if (value && this.viewport.width < this.overlayBreakpoints) { this._overlayDirection = value; + switch (value) { case 'start': this.transformOptions = "translate3d(0px, -100%, 0px)"; @@ -86,6 +88,10 @@ export class Overlay implements OnDestroy { } } + get overlayDirection(): string { + return this._overlayDirection; + } + @Input() set appendTo(val) { this._appendTo = val; } @@ -93,27 +99,46 @@ export class Overlay implements OnDestroy { get appendTo(): any { return this._appendTo; } + + @Input() set visible(value: boolean) { + this._visible = value; + } + + get visible(): boolean { + return this._visible; + } - get overlayBreakpoints() { + get overlayBreakpoints(): any { return this.config.overlayOptions ? this.config.overlayOptions.breakpoint : null; } - @ViewChild('overlay') overlayViewChild: ElementRef; + get viewport(): any { + this._viewport = DomHandler.getViewport(); + return this._viewport; + } + + _visible: boolean; _overlayDirection: string; + _viewport: any; + _overlayBreakpoints: number; _appendTo: any; transformOptions: string = "scaleY(0.8)"; - mask: HTMLDivElement; + documentResizeListener: any; - maskClickListener: Function; + responsive: boolean; - constructor(@Inject(DOCUMENT) private document: Document, public el: ElementRef, public renderer: Renderer2, private config: PrimeNGConfig, public overlayService: OverlayService) {} + constructor(@Inject(DOCUMENT) private document: Document, public el: ElementRef, public renderer: Renderer2, private config: PrimeNGConfig, public overlayService: OverlayService, private cd: ChangeDetectorRef) {} + ngOnInit() { + this.bindDocumentResizeListener(); + } + onOverlayClick(event: MouseEvent) { this.overlayService.add({ originalEvent: event, @@ -121,86 +146,71 @@ export class Overlay implements OnDestroy { }); } + onOverlayAnimationStart(event) { + this.onAnimationStart.emit(event); + } + + onOverlayAnimationEnd(event) { + if (event.toState === 'void') { + this.destroyOverlay(); + } + this.onAnimationEnd.emit(event); + } + appendOverlay() { - const viewport = DomHandler.getViewport(); if (this.autoZIndex) { - ZIndexUtils.set('overlay', this.overlayViewChild.nativeElement, this.baseZIndex + this.config.zIndex.overlay); + ZIndexUtils.set('modal', this.el.nativeElement, this.baseZIndex + this.config.zIndex.modal); } - if (viewport.width < this.overlayBreakpoints) { - this.appendMask(); + if (this.viewport.width < this.overlayBreakpoints) { + this.responsive = true; DomHandler.addClass(this.document.body, 'p-overflow-hidden'); DomHandler.addClass(this.overlayViewChild.nativeElement, 'p-overlay-responsive'); - this.mask.appendChild(this.el.nativeElement); + DomHandler.addClass(this.contentViewChild.nativeElement.firstChild, 'p-overlay-panel-static'); } else { + this.responsive = false; if (this.appendTo) { if (this.appendTo === 'body') { - this.document.body.appendChild(this.el.nativeElement); + this.document.body.appendChild(this.overlayViewChild.nativeElement); } else { - DomHandler.appendChild(this.el.nativeElement, this.appendTo); + DomHandler.appendChild(this.overlayViewChild.nativeElement, this.appendTo); } } } - - if (!this.overlayViewChild.nativeElement.style.minWidth) { - this.overlayViewChild.nativeElement.style.minWidth = DomHandler.getWidth(this.container) + 'px'; + if (!this.contentViewChild.nativeElement.style.minWidth) { + this.contentViewChild.nativeElement.style.minWidth = DomHandler.getWidth(this.container) + 'px'; } } alignOverlay() { - const viewport = DomHandler.getViewport(); - if(this.overlayViewChild) { - if (viewport.width < this.overlayBreakpoints) { + if (this.viewport.width < this.overlayBreakpoints) { switch (this.overlayDirection) { case 'start': - DomHandler.addClass(this.el.nativeElement, 'p-overlay-panel-start') + DomHandler.addClass(this.maskViewChild.nativeElement, 'p-overlay-panel-start') break; case 'center': - DomHandler.addClass(this.el.nativeElement, 'p-overlay-panel-center') + DomHandler.addClass(this.maskViewChild.nativeElement, 'p-overlay-panel-center') break; case 'end': - DomHandler.addClass(this.el.nativeElement, 'p-overlay-panel-end') + DomHandler.addClass(this.maskViewChild.nativeElement, 'p-overlay-panel-end') break; } } else { if (this.appendTo) { - DomHandler.absolutePosition(this.el.nativeElement.firstChild, this.container); + DomHandler.absolutePosition(this.overlayViewChild.nativeElement, this.container); } else { - DomHandler.relativePosition(this.el.nativeElement.firstChild, this.container); + DomHandler.relativePosition(this.overlayViewChild.nativeElement, this.container); } } } } - appendMask() { - if (!this.mask) { - this.mask = this.renderer.createElement('div'); - DomHandler.addMultipleClasses(this.mask, 'p-overlay-mask p-component-overlay-enter'); - ZIndexUtils.set('modal', this.mask, this.baseZIndex + this.config.zIndex.modal); - this.document.body.appendChild(this.mask); - this.blockScroll(); - this.bindMaskClickListener(); - } - } - - removeMask() { - this.unbindMaskClickListener(); - - if (this.mask) { - DomHandler.addClass(this.mask, 'p-component-overlay-leave'); - ZIndexUtils.clear(this.mask); - this.document.body.removeChild(this.mask); - this.mask = null; - this.unblockScroll(); - } - } - blockScroll() { DomHandler.addClass(this.document.body, 'p-overflow-hidden'); } @@ -209,34 +219,41 @@ export class Overlay implements OnDestroy { DomHandler.removeClass(this.document.body, 'p-overflow-hidden'); } - bindMaskClickListener() { - if (!this.maskClickListener) { - this.maskClickListener = this.renderer.listen(this.mask, 'click', () => { - this.removeMask(); - }); + bindDocumentResizeListener() { + if (!this.documentResizeListener) { + this.documentResizeListener = this.renderer.listen(window, 'resize', this.onWindowResize.bind(this)); } } - unbindMaskClickListener() { - if (this.maskClickListener) { - this.maskClickListener(); - this.maskClickListener = null; + unbindDocumentResizeListener() { + if (this.documentResizeListener) { + this.documentResizeListener(); + this.documentResizeListener = null; } } - - ngOnDestroy() { - if (this.maskClickListener) { - this.unbindMaskClickListener(); + + onWindowResize() { + if (this.visible) { + this.visible = false; + this.onOverlayHide.emit({visible: this.visible}); + this.cd.markForCheck(); } + } + + destroyOverlay() { + this.unblockScroll(); + this.unbindDocumentResizeListener(); - if (this.overlayViewChild && this.el.nativeElement) { - ZIndexUtils.clear(this.overlayViewChild.nativeElement); + if (this.overlayViewChild && this.overlayViewChild.nativeElement) { + ZIndexUtils.clear(this.el.nativeElement); this.overlayViewChild = null; } - if(this.mask) { - this.removeMask(); - } + this.onOverlayHide.emit({visible: this.visible}); + } + + ngOnDestroy() { + this.destroyOverlay(); } }