Skip to content

Commit

Permalink
Fixed #10426 - pStyleClass Directive
Browse files Browse the repository at this point in the history
  • Loading branch information
cagataycivici committed Jul 19, 2021
1 parent 611157e commit 7419dc6
Show file tree
Hide file tree
Showing 44 changed files with 709 additions and 2 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "primeng",
"version": "11.4.3",
"version": "11.4.4",
"license": "MIT",
"scripts": {
"ng": "ng",
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "primeng",
"version": "11.4.3",
"version": "11.4.4",
"repository": {
"type": "git",
"url": "https://github.com/primefaces/primeng"
Expand Down
6 changes: 6 additions & 0 deletions src/app/components/styleclass/ng-package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"$schema": "ng-packagr/ng-package.schema.json",
"lib": {
"entryFile": "public_api.ts"
}
}
1 change: 1 addition & 0 deletions src/app/components/styleclass/public_api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './styleclass';
196 changes: 196 additions & 0 deletions src/app/components/styleclass/styleclass.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
import { CommonModule} from '@angular/common';
import { NgModule, Directive, ElementRef, Input, Renderer2, OnDestroy, AfterViewInit } from '@angular/core';
import { DomHandler } from 'primeng/dom';

@Directive({
selector: '[pStyleClass]'
})
export class StyleClass implements AfterViewInit, OnDestroy {

constructor(public el: ElementRef, public renderer: Renderer2) {}

@Input('pStyleClass') selector: string;

@Input() enterClass: string;

@Input() enterActiveClass: string;

@Input() enterToClass: string;

@Input() leaveClass: string;

@Input() leaveActiveClass: string;

@Input() leaveToClass: string;

@Input() hideOnOutsideClick: boolean;

@Input() toggleClass: string;

eventListener: Function;

documentListener: Function;

target: HTMLElement;

enterListener: Function;

leaveListener: Function;

animating: boolean;

ngAfterViewInit() {
this.eventListener = this.renderer.listen(this.el.nativeElement, 'click', () => {
this.target = this.resolveTarget();

if (this.toggleClass) {
if (DomHandler.hasClass(this.target, this.toggleClass))
DomHandler.removeClass(this.target, this.toggleClass);
else
DomHandler.addClass(this.target, this.toggleClass);
}
else {
if (this.target.offsetParent === null)
this.enter();
else
this.leave();
}
});
}

enter() {
if (this.enterActiveClass) {
if (!this.animating) {
this.animating = true;

if (this.enterActiveClass === 'slidedown') {
this.target.style.height = '0px';
DomHandler.removeClass(this.target, 'hidden');
this.target.style.maxHeight = this.target.scrollHeight + 'px';
DomHandler.addClass(this.target, 'hidden');
this.target.style.height = '';
}

DomHandler.addClass(this.target, this.enterActiveClass);
if (this.enterClass) {
DomHandler.removeClass(this.target, this.enterClass);
}

this.enterListener = this.renderer.listen(this.target, 'animationend', () => {
DomHandler.removeClass(this.target, this.enterActiveClass);
if (this.enterToClass) {
DomHandler.addClass(this.target, this.enterToClass);
}
this.enterListener();

if (this.enterActiveClass === 'slidedown') {
this.target.style.maxHeight = '';
}
this.animating = false;
});
}
}
else {
if (this.enterClass) {
DomHandler.removeClass(this.target, this.enterClass);
}

if (this.enterToClass) {
DomHandler.addClass(this.target, this.enterToClass);
}
}

if (this.hideOnOutsideClick) {
this.bindDocumentListener();
}
}

leave() {
if (this.leaveActiveClass) {
if (!this.animating) {
this.animating = true;
DomHandler.addClass(this.target, this.leaveActiveClass);
if (this.leaveClass) {
DomHandler.removeClass(this.target, this.leaveClass);
}

this.leaveListener = this.renderer.listen(this.target, 'animationend', () => {
DomHandler.removeClass(this.target, this.leaveActiveClass);
if (this.leaveToClass) {
DomHandler.addClass(this.target, this.leaveToClass);
}
this.leaveListener();
this.animating = false;
});
}
}
else {
if (this.leaveClass) {
DomHandler.removeClass(this.target, this.leaveClass);
}

if (this.leaveToClass) {
DomHandler.addClass(this.target, this.leaveToClass);
}
}
}

resolveTarget() {
if (this.target) {
return this.target;
}

switch (this.selector) {
case '@next':
return this.el.nativeElement.nextElementSibling;

case '@prev':
return this.el.nativeElement.previousElementSibling;

case '@parent':
return this.el.nativeElement.parentElement;

case '@grandparent':
return this.el.nativeElement.parentElement.parentElement;

default:
return document.querySelector(this.selector);
}
}

bindDocumentListener() {
if (!this.documentListener) {
this.documentListener = this.renderer.listen(this.el.nativeElement.ownerDocument, 'click', event => {
if (getComputedStyle(this.target).getPropertyValue('position') === 'static') {
this.unbindDocumentListener();
}
else if (!this.el.nativeElement.isSameNode(event.target) && !this.el.nativeElement.contains(event.target) && !this.target.contains(event.target)) {
this.leave();
this.unbindDocumentListener();
}
});
}
}

unbindDocumentListener() {
if (this.documentListener) {
this.documentListener();
this.documentListener = null;
}
}

ngOnDestroy() {
this.target = null;
if (this.eventListener) {
this.eventListener();
}
this.unbindDocumentListener();
}
}

@NgModule({
imports: [CommonModule],
exports: [StyleClass],
declarations: [StyleClass]
})
export class StyleClassModule { }
1 change: 1 addition & 0 deletions src/app/showcase/app-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ import { HomeComponent } from './components/home/home.component';
{path: 'splitter', loadChildren: () => import('./components/splitter/splitterdemo.module').then(m => m.SplitterDemoModule)},
{path: 'steps', loadChildren: () => import('./components/steps/stepsdemo.module').then(m => m.StepsDemoModule)},
{path: 'support', loadChildren: () => import('./components/support/support.module').then(m => m.SupportModule)},
{path: 'styleclass', loadChildren: () => import('./components/styleclass/styleclassdemo.module').then(m => m.StyleClassDemoModule)},
{path: 'tag', loadChildren: () => import('./components/tag/tagdemo.module').then(m => m.TagDemoModule)},
{path: 'table', loadChildren: () => import('./components/table/tabledemo.module').then(m => m.TableDemoModule)},
{path: 'tabmenu', loadChildren: () => import('./components/tabmenu/tabmenudemo.module').then(m => m.TabMenuDemoModule)},
Expand Down
1 change: 1 addition & 0 deletions src/app/showcase/app.menu.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ declare let gtag: Function;
<div class="menu-items">
<a [routerLink]=" ['/defer']" routerLinkActive="router-link-exact-active">Defer</a>
<a [routerLink]=" ['/focustrap']" routerLinkActive="router-link-exact-active">FocusTrap</a>
<a [routerLink]=" ['/styleclass']" routerLinkActive="router-link-exact-active">StyleClass <span class="p-tag">New</span></a>
<a [routerLink]=" ['/ripple']" routerLinkActive="router-link-exact-active">Ripple</a>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router'
import {StyleClassDemo} from './styleclassdemo';

@NgModule({
imports: [
RouterModule.forChild([
{path:'',component: StyleClassDemo}
])
],
exports: [
RouterModule
]
})
export class StyleClassDemoRoutingModule {}
Loading

0 comments on commit 7419dc6

Please sign in to comment.