From 4aae29017f1c3bf40f530ec184c430ac5d84fe7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=87etin?= <69278826+cetincakiroglu@users.noreply.github.com> Date: Wed, 2 Nov 2022 11:10:12 +0300 Subject: [PATCH 1/2] Fixed #12116 - TreeSelect | Add p-overlay --- src/app/components/tree/tree.ts | 1 - src/app/components/treeselect/treeselect.css | 10 - src/app/components/treeselect/treeselect.ts | 215 +++++++------------ 3 files changed, 78 insertions(+), 148 deletions(-) diff --git a/src/app/components/tree/tree.ts b/src/app/components/tree/tree.ts index dfc9ab2e8b8..2af30b34c59 100755 --- a/src/app/components/tree/tree.ts +++ b/src/app/components/tree/tree.ts @@ -887,7 +887,6 @@ export class Tree implements OnInit, AfterContentInit, OnChanges, OnDestroy, Blo onNodeClick(event, node: TreeNode) { let eventTarget = event.target; - if (DomHandler.hasClass(eventTarget, 'p-tree-toggler') || DomHandler.hasClass(eventTarget, 'p-tree-toggler-icon')) { return; } else if (this.selectionMode) { diff --git a/src/app/components/treeselect/treeselect.css b/src/app/components/treeselect/treeselect.css index 928584839db..5479469e6d6 100755 --- a/src/app/components/treeselect/treeselect.css +++ b/src/app/components/treeselect/treeselect.css @@ -38,16 +38,6 @@ flex: 0 0 auto; } -.p-treeselect .p-treeselect-panel { - min-width: 100%; -} - -.p-treeselect-panel { - position: absolute; - top: 0; - left: 0; -} - .p-treeselect-items-wrapper { overflow: auto; } diff --git a/src/app/components/treeselect/treeselect.ts b/src/app/components/treeselect/treeselect.ts index b924693f04d..f3d1c0801a8 100755 --- a/src/app/components/treeselect/treeselect.ts +++ b/src/app/components/treeselect/treeselect.ts @@ -1,12 +1,13 @@ import { NgModule, Component, EventEmitter, Output, Input, ChangeDetectionStrategy, ViewEncapsulation, ContentChildren, AfterContentInit, TemplateRef, QueryList, forwardRef, ChangeDetectorRef, ViewChild, ElementRef } from '@angular/core'; import { CommonModule } from '@angular/common'; import { RippleModule } from 'primeng/ripple'; -import { OverlayService, PrimeNGConfig, PrimeTemplate, SharedModule, TranslationKeys, TreeNode } from 'primeng/api'; +import { OverlayService, PrimeNGConfig, PrimeTemplate, SharedModule, TreeNode, OverlayOptions } from 'primeng/api'; import { animate, style, transition, trigger, AnimationEvent } from '@angular/animations'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { ConnectedOverlayScrollHandler, DomHandler } from 'primeng/dom'; import { Tree, TreeModule } from 'primeng/tree'; import { ObjectUtils, ZIndexUtils } from 'primeng/utils'; +import { Overlay, OverlayModule } from 'primeng/overlay'; export const TREESELECT_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, @@ -57,17 +58,20 @@ export const TREESELECT_VALUE_ACCESSOR: any = {
-
+
@@ -106,7 +110,6 @@ export const TREESELECT_VALUE_ACCESSOR: any = { [filterMode]="filterMode" [filterPlaceholder]="filterPlaceholder" [filterLocale]="filterLocale" - [filterInputAutoFocus]="filterInputAutoFocus" [filteredNodes]="filteredNodes" [_templateMap]="templateMap" > @@ -118,11 +121,11 @@ export const TREESELECT_VALUE_ACCESSOR: any = {
-
+
+
`, styleUrls: ['./treeselect.css'], - animations: [trigger('overlayAnimation', [transition(':enter', [style({ opacity: 0, transform: 'scaleY(0.8)' }), animate('{{showTransitionParams}}')]), transition(':leave', [animate('{{hideTransitionParams}}', style({ opacity: 0 }))])])], host: { class: 'p-element p-inputwrapper', '[class.p-inputwrapper-filled]': '!emptyValue', @@ -134,6 +137,7 @@ export const TREESELECT_VALUE_ACCESSOR: any = { encapsulation: ViewEncapsulation.None }) export class TreeSelect implements AfterContentInit { + @Input() type: string = 'button'; @Input() inputId: string; @@ -168,6 +172,10 @@ export class TreeSelect implements AfterContentInit { @Input() labelStyleClass: string; + @Input() overlayVisible: boolean; + + @Input() overlayOptions: OverlayOptions; + @Input() emptyMessage: string = ''; @Input() appendTo: any; @@ -200,9 +208,44 @@ export class TreeSelect implements AfterContentInit { this.updateTreeState(); } - @Input() showTransitionOptions: string = '.12s cubic-bezier(0, 0, 0.2, 1)'; + _autoZIndex: boolean; + @Input() get autoZIndex(): boolean { + return this._autoZIndex; + } + set autoZIndex(val: boolean) { + this._autoZIndex = val; + console.warn('The autoZIndex property is deprecated since v14.2.0, use overlayOptions property instead.'); + } - @Input() hideTransitionOptions: string = '.1s linear'; + /* @deprecated */ + _baseZIndex: number; + @Input() get baseZIndex(): number { + return this._baseZIndex; + } + set baseZIndex(val: number) { + this._baseZIndex = val; + console.warn('The baseZIndex property is deprecated since v14.2.0, use overlayOptions property instead.'); + } + + /* @deprecated */ + _showTransitionOptions: string; + @Input() get showTransitionOptions(): string { + return this._showTransitionOptions; + } + set showTransitionOptions(val: string) { + this._showTransitionOptions = val; + console.warn('The showTransitionOptions property is deprecated since v14.2.0, use overlayOptions property instead.'); + } + + /* @deprecated */ + _hideTransitionOptions: boolean; + @Input() get hideTransitionOptions(): boolean { + return this._hideTransitionOptions; + } + set hideTransitionOptions(val: boolean) { + this._hideTransitionOptions = val; + console.warn('The hideTransitionOptions property is deprecated since v14.2.0, use overlayOptions property instead.'); + } @ContentChildren(PrimeTemplate) templates: QueryList; @@ -214,6 +257,8 @@ export class TreeSelect implements AfterContentInit { @ViewChild('tree') treeViewChild: Tree; + @ViewChild('overlay') overlayViewChild: Overlay; + @Output() onNodeExpand: EventEmitter = new EventEmitter(); @Output() onNodeCollapse: EventEmitter = new EventEmitter(); @@ -246,8 +291,6 @@ export class TreeSelect implements AfterContentInit { focused: boolean; - overlayVisible: boolean; - selfChange: boolean; value; @@ -262,8 +305,6 @@ export class TreeSelect implements AfterContentInit { scrollHandler: any; - resizeListener: any; - overlayEl: any; onModelChange: Function = () => {}; @@ -311,7 +352,7 @@ export class TreeSelect implements AfterContentInit { switch (event.toState) { case 'visible': this.overlayEl = event.element; - this.onOverlayEnter(); + this.onShow.emit(event); break; } } @@ -319,7 +360,7 @@ export class TreeSelect implements AfterContentInit { onOverlayAnimationDone(event: AnimationEvent) { switch (event.toState) { case 'void': - this.onOverlayLeave(); + this.onHide.emit(event); break; } } @@ -340,6 +381,11 @@ export class TreeSelect implements AfterContentInit { } } + isOverlayClick(event: MouseEvent) { + let targetNode = event.target; + return this.overlayEl ? this.overlayEl.isSameNode(targetNode) || this.overlayEl.contains(targetNode) : false; + } + onKeyDown(event) { switch (event.which) { //down @@ -400,7 +446,11 @@ export class TreeSelect implements AfterContentInit { hide() { this.overlayVisible = false; - this.resetFilter(); + + if (this.resetFilterOnHide) { + this.resetFilter(); + } + this.cd.markForCheck(); } @@ -427,13 +477,6 @@ export class TreeSelect implements AfterContentInit { } } - onOverlayClick(event) { - this.overlayService.add({ - originalEvent: event, - target: this.el.nativeElement - }); - } - updateTreeState() { if (this.value) { let selectedNodes = this.selectionMode === 'single' ? [this.value] : [...this.value]; @@ -561,30 +604,6 @@ export class TreeSelect implements AfterContentInit { this.onNodeUnselect.emit(node); } - onOverlayEnter() { - ZIndexUtils.set('overlay', this.overlayEl, this.config.zIndex.overlay); - - if (this.filter && this.filterInputAutoFocus) { - this.filterViewChild.nativeElement.focus(); - } - - this.appendContainer(); - this.alignOverlay(); - this.bindOutsideClickListener(); - this.bindScrollListener(); - this.bindResizeListener(); - this.onShow.emit(); - } - - onOverlayLeave() { - this.unbindOutsideClickListener(); - this.unbindScrollListener(); - this.unbindResizeListener(); - ZIndexUtils.clear(this.overlayEl); - this.overlayEl = null; - this.onHide.emit(); - } - onFocus() { this.focused = true; } @@ -607,100 +626,22 @@ export class TreeSelect implements AfterContentInit { this.onModelTouched = fn; } + onOverlayHide() { + this.onModelTouched(); + } + setDisabledState(val: boolean): void { this.disabled = val; this.cd.markForCheck(); } - appendContainer() { - if (this.appendTo) { - if (this.appendTo === 'body') document.body.appendChild(this.overlayEl); - else document.getElementById(this.appendTo).appendChild(this.overlayEl); - } - } - - restoreAppend() { - if (this.overlayEl && this.appendTo) { - if (this.appendTo === 'body') document.body.removeChild(this.overlayEl); - else document.getElementById(this.appendTo).removeChild(this.overlayEl); - } - } - - alignOverlay() { - if (this.appendTo) { - DomHandler.absolutePosition(this.overlayEl, this.containerEl.nativeElement); - this.overlayEl.style.minWidth = DomHandler.getOuterWidth(this.containerEl.nativeElement) + 'px'; - } else { - DomHandler.relativePosition(this.overlayEl, this.containerEl.nativeElement); - } - } - - bindOutsideClickListener() { - if (!this.outsideClickListener) { - this.outsideClickListener = (event) => { - if (this.overlayVisible && this.overlayEl && !this.containerEl.nativeElement.contains(event.target) && !this.overlayEl.contains(event.target)) { - this.hide(); - } - }; - document.addEventListener('click', this.outsideClickListener); - } - } - - unbindOutsideClickListener() { - if (this.outsideClickListener) { - document.removeEventListener('click', this.outsideClickListener); - this.outsideClickListener = null; - } - } - - bindScrollListener() { - if (!this.scrollHandler) { - this.scrollHandler = new ConnectedOverlayScrollHandler(this.containerEl.nativeElement, () => { - if (this.overlayVisible) { - this.hide(); - } - }); - } - - this.scrollHandler.bindScrollListener(); - } - - unbindScrollListener() { - if (this.scrollHandler) { - this.scrollHandler.unbindScrollListener(); - } - } - - bindResizeListener() { - if (!this.resizeListener) { - this.resizeListener = () => { - if (this.overlayVisible && !DomHandler.isTouchDevice()) { - this.hide(); - } - }; - window.addEventListener('resize', this.resizeListener); - } - } - - unbindResizeListener() { - if (this.resizeListener) { - window.removeEventListener('resize', this.resizeListener); - this.resizeListener = null; - } - } - ngOnDestroy() { - this.restoreAppend(); - this.unbindOutsideClickListener(); - this.unbindResizeListener(); - if (this.scrollHandler) { this.scrollHandler.destroy(); this.scrollHandler = null; } if (this.overlayEl) { - ZIndexUtils.clear(this.overlayEl); this.overlayEl = null; } } @@ -737,7 +678,7 @@ export class TreeSelect implements AfterContentInit { } @NgModule({ - imports: [CommonModule, RippleModule, SharedModule, TreeModule], + imports: [CommonModule, RippleModule, SharedModule, TreeModule, OverlayModule], exports: [TreeSelect, SharedModule, TreeModule], declarations: [TreeSelect] }) From 9c1bb5950687c26bfe138d45af4b4f7d53c2e1c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=87etin?= <69278826+cetincakiroglu@users.noreply.github.com> Date: Wed, 2 Nov 2022 11:30:05 +0300 Subject: [PATCH 2/2] Refactor --- src/app/components/treeselect/treeselect.ts | 130 +++++++++----------- 1 file changed, 60 insertions(+), 70 deletions(-) diff --git a/src/app/components/treeselect/treeselect.ts b/src/app/components/treeselect/treeselect.ts index f3d1c0801a8..da4515b0b10 100755 --- a/src/app/components/treeselect/treeselect.ts +++ b/src/app/components/treeselect/treeselect.ts @@ -2,12 +2,12 @@ import { NgModule, Component, EventEmitter, Output, Input, ChangeDetectionStrate import { CommonModule } from '@angular/common'; import { RippleModule } from 'primeng/ripple'; import { OverlayService, PrimeNGConfig, PrimeTemplate, SharedModule, TreeNode, OverlayOptions } from 'primeng/api'; -import { animate, style, transition, trigger, AnimationEvent } from '@angular/animations'; +import { AnimationEvent } from '@angular/animations'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; -import { ConnectedOverlayScrollHandler, DomHandler } from 'primeng/dom'; +import { DomHandler } from 'primeng/dom'; import { Tree, TreeModule } from 'primeng/tree'; -import { ObjectUtils, ZIndexUtils } from 'primeng/utils'; -import { Overlay, OverlayModule } from 'primeng/overlay'; +import { ObjectUtils } from 'primeng/utils'; +import { OverlayModule } from 'primeng/overlay'; export const TREESELECT_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, @@ -59,7 +59,6 @@ export const TREESELECT_VALUE_ACCESSOR: any = { -
- -
-
- - +
+ +
+
+ + +
+
- -
-
- - - - - - - -
- +
+ + + + + + + +
+
@@ -137,7 +136,6 @@ export const TREESELECT_VALUE_ACCESSOR: any = { encapsulation: ViewEncapsulation.None }) export class TreeSelect implements AfterContentInit { - @Input() type: string = 'button'; @Input() inputId: string; @@ -257,7 +255,7 @@ export class TreeSelect implements AfterContentInit { @ViewChild('tree') treeViewChild: Tree; - @ViewChild('overlay') overlayViewChild: Overlay; + @ViewChild('panel') panelViewChild: ElementRef; @Output() onNodeExpand: EventEmitter = new EventEmitter(); @@ -305,8 +303,6 @@ export class TreeSelect implements AfterContentInit { scrollHandler: any; - overlayEl: any; - onModelChange: Function = () => {}; onModelTouched: Function = () => {}; @@ -351,7 +347,6 @@ export class TreeSelect implements AfterContentInit { onOverlayAnimationStart(event: AnimationEvent) { switch (event.toState) { case 'visible': - this.overlayEl = event.element; this.onShow.emit(event); break; } @@ -372,7 +367,7 @@ export class TreeSelect implements AfterContentInit { } onClick(event) { - if (!this.disabled && (!this.overlayEl || !this.overlayEl.contains(event.target)) && !DomHandler.hasClass(event.target, 'p-treeselect-close')) { + if (!this.disabled && !DomHandler.hasClass(event.target, 'p-treeselect-close')) { if (this.overlayVisible) { this.hide(); } else this.show(); @@ -381,11 +376,6 @@ export class TreeSelect implements AfterContentInit { } } - isOverlayClick(event: MouseEvent) { - let targetNode = event.target; - return this.overlayEl ? this.overlayEl.isSameNode(targetNode) || this.overlayEl.contains(targetNode) : false; - } - onKeyDown(event) { switch (event.which) { //down @@ -393,8 +383,8 @@ export class TreeSelect implements AfterContentInit { if (!this.overlayVisible && event.altKey) { this.show(); event.preventDefault(); - } else if (this.overlayVisible && this.overlayEl) { - let focusableElements = DomHandler.getFocusableElements(this.overlayEl); + } else if (this.overlayVisible && this.panelViewChild) { + let focusableElements = DomHandler.getFocusableElements(this.panelViewChild.nativeElement); if (focusableElements && focusableElements.length > 0) { focusableElements[0].focus(); @@ -641,9 +631,9 @@ export class TreeSelect implements AfterContentInit { this.scrollHandler = null; } - if (this.overlayEl) { - this.overlayEl = null; - } + // if (this.overlayEl) { + // this.overlayEl = null; + // } } containerClass() {