primeng
Version:
PrimeNG is a premium UI library for Angular featuring a rich set of 90+ components, a theme designer, various theme alternatives such as Material, Bootstrap, Tailwind, premium templates and professional support. In addition, it integrates with PrimeBlock,
332 lines (328 loc) • 16.1 kB
JavaScript
import * as i0 from '@angular/core';
import { inject, ElementRef, Renderer2, input, booleanAttribute, HostListener, Directive, NgModule } from '@angular/core';
import { getTargetElement, hasClass, removeClass, addClass, isElement } from '@primeuix/utils';
/**
* StyleClass manages css classes declaratively to during enter/leave animations or just to toggle classes on an element.
* @group Components
*/
class StyleClass {
el = inject(ElementRef);
renderer = inject(Renderer2);
/**
* Selector to define the target element. Available selectors are '@next', '@prev', '@parent' and '@grandparent'.
* @group Props
*/
selector = input(undefined, { ...(ngDevMode ? { debugName: "selector" } : /* istanbul ignore next */ {}), alias: 'pStyleClass' });
/**
* Style class to add when item begins to get displayed.
* @group Props
*/
enterFromClass = input(/* @ts-ignore */
...(ngDevMode ? [undefined, { debugName: "enterFromClass" }] : /* istanbul ignore next */ []));
/**
* Style class to add during enter animation.
* @group Props
*/
enterActiveClass = input(/* @ts-ignore */
...(ngDevMode ? [undefined, { debugName: "enterActiveClass" }] : /* istanbul ignore next */ []));
/**
* Style class to add when item begins to get displayed.
* @group Props
*/
enterToClass = input(/* @ts-ignore */
...(ngDevMode ? [undefined, { debugName: "enterToClass" }] : /* istanbul ignore next */ []));
/**
* Style class to add when item begins to get hidden.
* @group Props
*/
leaveFromClass = input(/* @ts-ignore */
...(ngDevMode ? [undefined, { debugName: "leaveFromClass" }] : /* istanbul ignore next */ []));
/**
* Style class to add during leave animation.
* @group Props
*/
leaveActiveClass = input(/* @ts-ignore */
...(ngDevMode ? [undefined, { debugName: "leaveActiveClass" }] : /* istanbul ignore next */ []));
/**
* Style class to add when leave animation is completed.
* @group Props
*/
leaveToClass = input(/* @ts-ignore */
...(ngDevMode ? [undefined, { debugName: "leaveToClass" }] : /* istanbul ignore next */ []));
/**
* Whether to trigger leave animation when outside of the element is clicked.
* @group Props
*/
hideOnOutsideClick = input(undefined, { ...(ngDevMode ? { debugName: "hideOnOutsideClick" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
/**
* Adds or removes a class when no enter-leave animation is required.
* @group Props
*/
toggleClass = input(/* @ts-ignore */
...(ngDevMode ? [undefined, { debugName: "toggleClass" }] : /* istanbul ignore next */ []));
/**
* Whether to trigger leave animation when escape key pressed.
* @group Props
*/
hideOnEscape = input(undefined, { ...(ngDevMode ? { debugName: "hideOnEscape" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
/**
* Whether to trigger leave animation when the target element resized.
* @group Props
*/
hideOnResize = input(undefined, { ...(ngDevMode ? { debugName: "hideOnResize" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
/**
* Target element to listen resize. Valid values are "window", "document" or target element selector.
* @group Props
*/
resizeSelector = input(/* @ts-ignore */
...(ngDevMode ? [undefined, { debugName: "resizeSelector" }] : /* istanbul ignore next */ []));
eventListener;
documentClickListener;
documentKeydownListener;
windowResizeListener;
resizeObserver;
target;
enterListener;
leaveListener;
animating;
_enterClass;
_leaveClass;
_resizeTarget;
clickListener() {
this.target ||= getTargetElement(this.selector(), this.el.nativeElement);
if (this.toggleClass()) {
this.toggle();
}
else {
if (this.target?.offsetParent === null)
this.enter();
else
this.leave();
}
}
toggle() {
const toggleClass = this.toggleClass();
if (hasClass(this.target, toggleClass))
removeClass(this.target, toggleClass);
else
addClass(this.target, toggleClass);
}
enter() {
const enterActiveClass = this.enterActiveClass();
const enterFromClass = this.enterFromClass();
const enterToClass = this.enterToClass();
if (enterActiveClass) {
if (!this.animating) {
this.animating = true;
if (enterActiveClass.includes('slidedown')) {
this.target.style.height = '0px';
removeClass(this.target, enterFromClass || 'hidden');
this.target.style.maxHeight = this.target.scrollHeight + 'px';
addClass(this.target, enterFromClass || 'hidden');
this.target.style.height = '';
}
addClass(this.target, enterActiveClass);
if (enterFromClass) {
removeClass(this.target, enterFromClass);
}
this.enterListener = this.renderer.listen(this.target, 'animationend', () => {
removeClass(this.target, enterActiveClass);
if (enterToClass) {
addClass(this.target, enterToClass);
}
this.enterListener && this.enterListener();
if (enterActiveClass.includes('slidedown')) {
this.target.style.maxHeight = '';
}
this.animating = false;
});
}
}
else {
if (enterFromClass) {
removeClass(this.target, enterFromClass);
}
if (enterToClass) {
addClass(this.target, enterToClass);
}
}
if (this.hideOnOutsideClick()) {
this.bindDocumentClickListener();
}
if (this.hideOnEscape()) {
this.bindDocumentKeydownListener();
}
if (this.hideOnResize()) {
this.bindResizeListener();
}
}
leave() {
const leaveActiveClass = this.leaveActiveClass();
const leaveFromClass = this.leaveFromClass();
const leaveToClass = this.leaveToClass();
if (leaveActiveClass) {
if (!this.animating) {
this.animating = true;
addClass(this.target, leaveActiveClass);
if (leaveFromClass) {
removeClass(this.target, leaveFromClass);
}
this.leaveListener = this.renderer.listen(this.target, 'animationend', () => {
removeClass(this.target, leaveActiveClass);
if (leaveToClass) {
addClass(this.target, leaveToClass);
}
this.leaveListener && this.leaveListener();
this.animating = false;
});
}
}
else {
if (leaveFromClass) {
removeClass(this.target, leaveFromClass);
}
if (leaveToClass) {
addClass(this.target, leaveToClass);
}
}
if (this.hideOnOutsideClick()) {
this.unbindDocumentClickListener();
}
if (this.hideOnEscape()) {
this.unbindDocumentKeydownListener();
}
if (this.hideOnResize()) {
this.unbindResizeListener();
}
}
bindDocumentClickListener() {
if (!this.documentClickListener) {
this.documentClickListener = this.renderer.listen(this.el.nativeElement.ownerDocument, 'click', (event) => {
if (!this.isVisible() || getComputedStyle(this.target).getPropertyValue('position') === 'static')
this.unbindDocumentClickListener();
else if (this.isOutsideClick(event))
this.leave();
});
}
}
bindDocumentKeydownListener() {
if (!this.documentKeydownListener) {
this.documentKeydownListener = this.renderer.listen(this.el.nativeElement.ownerDocument, 'keydown', (event) => {
const { key, keyCode, which } = event;
if (!this.isVisible() || getComputedStyle(this.target).getPropertyValue('position') === 'static')
this.unbindDocumentKeydownListener();
if (this.isVisible() && key === 'Escape' && keyCode === 27 && which === 27)
this.leave();
});
}
}
isVisible() {
return this.target.offsetParent !== null;
}
isOutsideClick(event) {
return !this.el.nativeElement.isSameNode(event.target) && !this.el.nativeElement.contains(event.target) && !this.target.contains(event.target);
}
unbindDocumentClickListener() {
if (this.documentClickListener) {
this.documentClickListener();
this.documentClickListener = null;
}
}
unbindDocumentKeydownListener() {
if (this.documentKeydownListener) {
this.documentKeydownListener();
this.documentKeydownListener = null;
}
}
bindResizeListener() {
this._resizeTarget = getTargetElement(this.resizeSelector());
if (isElement(this._resizeTarget)) {
this.bindElementResizeListener();
}
else {
this.bindWindowResizeListener();
}
}
unbindResizeListener() {
this.unbindWindowResizeListener();
this.unbindElementResizeListener();
}
bindWindowResizeListener() {
if (!this.windowResizeListener) {
this.windowResizeListener = this.renderer.listen(window, 'resize', () => {
if (!this.isVisible()) {
this.unbindWindowResizeListener();
}
else {
this.leave();
}
});
}
}
unbindWindowResizeListener() {
if (this.windowResizeListener) {
this.windowResizeListener();
this.windowResizeListener = null;
}
}
bindElementResizeListener() {
if (!this.resizeObserver && this._resizeTarget) {
let isFirstResize = true;
this.resizeObserver = new ResizeObserver(() => {
if (isFirstResize) {
isFirstResize = false;
return;
}
if (this.isVisible()) {
this.leave();
}
});
this.resizeObserver.observe(this._resizeTarget);
}
}
unbindElementResizeListener() {
if (this.resizeObserver) {
this.resizeObserver.disconnect();
this.resizeObserver = undefined;
}
}
ngOnDestroy() {
this.target = null;
this._resizeTarget = null;
if (this.eventListener) {
this.eventListener();
}
this.unbindDocumentClickListener();
this.unbindDocumentKeydownListener();
this.unbindResizeListener();
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: StyleClass, deps: [], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.6", type: StyleClass, isStandalone: true, selector: "[pStyleClass]", inputs: { selector: { classPropertyName: "selector", publicName: "pStyleClass", isSignal: true, isRequired: false, transformFunction: null }, enterFromClass: { classPropertyName: "enterFromClass", publicName: "enterFromClass", isSignal: true, isRequired: false, transformFunction: null }, enterActiveClass: { classPropertyName: "enterActiveClass", publicName: "enterActiveClass", isSignal: true, isRequired: false, transformFunction: null }, enterToClass: { classPropertyName: "enterToClass", publicName: "enterToClass", isSignal: true, isRequired: false, transformFunction: null }, leaveFromClass: { classPropertyName: "leaveFromClass", publicName: "leaveFromClass", isSignal: true, isRequired: false, transformFunction: null }, leaveActiveClass: { classPropertyName: "leaveActiveClass", publicName: "leaveActiveClass", isSignal: true, isRequired: false, transformFunction: null }, leaveToClass: { classPropertyName: "leaveToClass", publicName: "leaveToClass", isSignal: true, isRequired: false, transformFunction: null }, hideOnOutsideClick: { classPropertyName: "hideOnOutsideClick", publicName: "hideOnOutsideClick", isSignal: true, isRequired: false, transformFunction: null }, toggleClass: { classPropertyName: "toggleClass", publicName: "toggleClass", isSignal: true, isRequired: false, transformFunction: null }, hideOnEscape: { classPropertyName: "hideOnEscape", publicName: "hideOnEscape", isSignal: true, isRequired: false, transformFunction: null }, hideOnResize: { classPropertyName: "hideOnResize", publicName: "hideOnResize", isSignal: true, isRequired: false, transformFunction: null }, resizeSelector: { classPropertyName: "resizeSelector", publicName: "resizeSelector", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "clickListener()" } }, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: StyleClass, decorators: [{
type: Directive,
args: [{
selector: '[pStyleClass]',
standalone: true
}]
}], propDecorators: { selector: [{ type: i0.Input, args: [{ isSignal: true, alias: "pStyleClass", required: false }] }], enterFromClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "enterFromClass", required: false }] }], enterActiveClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "enterActiveClass", required: false }] }], enterToClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "enterToClass", required: false }] }], leaveFromClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "leaveFromClass", required: false }] }], leaveActiveClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "leaveActiveClass", required: false }] }], leaveToClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "leaveToClass", required: false }] }], hideOnOutsideClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideOnOutsideClick", required: false }] }], toggleClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "toggleClass", required: false }] }], hideOnEscape: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideOnEscape", required: false }] }], hideOnResize: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideOnResize", required: false }] }], resizeSelector: [{ type: i0.Input, args: [{ isSignal: true, alias: "resizeSelector", required: false }] }], clickListener: [{
type: HostListener,
args: ['click']
}] } });
class StyleClassModule {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: StyleClassModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.6", ngImport: i0, type: StyleClassModule, imports: [StyleClass], exports: [StyleClass] });
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: StyleClassModule });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: StyleClassModule, decorators: [{
type: NgModule,
args: [{
imports: [StyleClass],
exports: [StyleClass]
}]
}] });
/**
* Generated bundle index. Do not edit.
*/
export { StyleClass, StyleClassModule };
//# sourceMappingURL=primeng-styleclass.mjs.map