primeng
Version:
[](https://badge.fury.io/js/primeng) [](https://www.npmjs.com/package/primeng) [ • 25.7 kB
JavaScript
import { DOCUMENT, NgIf, NgTemplateOutlet, NgStyle, NgClass } from '@angular/common';
import * as i0 from '@angular/core';
import { booleanAttribute, Directive, Inject, Input, EventEmitter, numberAttribute, Component, ChangeDetectionStrategy, ViewEncapsulation, Output, ContentChildren, NgModule } from '@angular/core';
import { PrimeTemplate, SharedModule } from 'primeng/api';
import { AutoFocus } from 'primeng/autofocus';
import { DomHandler } from 'primeng/dom';
import { SpinnerIcon } from 'primeng/icons/spinner';
import { Ripple } from 'primeng/ripple';
import { ObjectUtils } from 'primeng/utils';
const INTERNAL_BUTTON_CLASSES = {
button: 'p-button',
component: 'p-component',
iconOnly: 'p-button-icon-only',
disabled: 'p-disabled',
loading: 'p-button-loading',
labelOnly: 'p-button-loading-label-only'
};
/**
* Button directive is an extension to button component.
* @group Components
*/
class ButtonDirective {
el;
document;
/**
* Position of the icon.
* @group Props
*/
iconPos = 'left';
/**
* Uses to pass attributes to the loading icon's DOM element.
* @group Props
*/
loadingIcon;
/**
* Text of the button.
* @group Props
*/
get label() {
return this._label;
}
set label(val) {
this._label = val;
if (this.initialized) {
this.updateLabel();
this.updateIcon();
this.setStyleClass();
}
}
/**
* Name of the icon.
* @group Props
*/
get icon() {
return this._icon;
}
set icon(val) {
this._icon = val;
if (this.initialized) {
this.updateIcon();
this.setStyleClass();
}
}
/**
* Whether the button is in loading state.
* @group Props
*/
get loading() {
return this._loading;
}
set loading(val) {
this._loading = val;
if (this.initialized) {
this.updateIcon();
this.setStyleClass();
}
}
/**
* Defines the style of the button.
* @group Props
*/
severity;
/**
* Add a shadow to indicate elevation.
* @group Props
*/
raised = false;
/**
* Add a circular border radius to the button.
* @group Props
*/
rounded = false;
/**
* Add a textual class to the button without a background initially.
* @group Props
*/
text = false;
/**
* Add a border class without a background initially.
* @group Props
*/
outlined = false;
/**
* Defines the size of the button.
* @group Props
*/
size = null;
/**
* Add a plain textual class to the button without a background initially.
* @group Props
*/
plain = false;
_label;
_icon;
_loading = false;
initialized;
get htmlElement() {
return this.el.nativeElement;
}
_internalClasses = Object.values(INTERNAL_BUTTON_CLASSES);
constructor(el, document) {
this.el = el;
this.document = document;
}
ngAfterViewInit() {
DomHandler.addMultipleClasses(this.htmlElement, this.getStyleClass().join(' '));
this.createIcon();
this.createLabel();
this.initialized = true;
}
getStyleClass() {
const styleClass = [INTERNAL_BUTTON_CLASSES.button, INTERNAL_BUTTON_CLASSES.component];
if (this.icon && !this.label && ObjectUtils.isEmpty(this.htmlElement.textContent)) {
styleClass.push(INTERNAL_BUTTON_CLASSES.iconOnly);
}
if (this.loading) {
styleClass.push(INTERNAL_BUTTON_CLASSES.disabled, INTERNAL_BUTTON_CLASSES.loading);
if (!this.icon && this.label) {
styleClass.push(INTERNAL_BUTTON_CLASSES.labelOnly);
}
if (this.icon && !this.label && !ObjectUtils.isEmpty(this.htmlElement.textContent)) {
styleClass.push(INTERNAL_BUTTON_CLASSES.iconOnly);
}
}
if (this.text) {
styleClass.push('p-button-text');
}
if (this.severity) {
styleClass.push(`p-button-${this.severity}`);
}
if (this.plain) {
styleClass.push('p-button-plain');
}
if (this.raised) {
styleClass.push('p-button-raised');
}
if (this.size) {
styleClass.push(`p-button-${this.size}`);
}
if (this.outlined) {
styleClass.push('p-button-outlined');
}
if (this.rounded) {
styleClass.push('p-button-rounded');
}
if (this.size === 'small') {
styleClass.push('p-button-sm');
}
if (this.size === 'large') {
styleClass.push('p-button-lg');
}
return styleClass;
}
setStyleClass() {
const styleClass = this.getStyleClass();
this.htmlElement.classList.remove(...this._internalClasses);
this.htmlElement.classList.add(...styleClass);
}
createLabel() {
const created = DomHandler.findSingle(this.htmlElement, '.p-button-label');
if (!created && this.label) {
let labelElement = this.document.createElement('span');
if (this.icon && !this.label) {
labelElement.setAttribute('aria-hidden', 'true');
}
labelElement.className = 'p-button-label';
labelElement.appendChild(this.document.createTextNode(this.label));
this.htmlElement.appendChild(labelElement);
}
}
createIcon() {
const created = DomHandler.findSingle(this.htmlElement, '.p-button-icon');
if (!created && (this.icon || this.loading)) {
let iconElement = this.document.createElement('span');
iconElement.className = 'p-button-icon';
iconElement.setAttribute('aria-hidden', 'true');
let iconPosClass = this.label ? 'p-button-icon-' + this.iconPos : null;
if (iconPosClass) {
DomHandler.addClass(iconElement, iconPosClass);
}
let iconClass = this.getIconClass();
if (iconClass) {
DomHandler.addMultipleClasses(iconElement, iconClass);
}
this.htmlElement.insertBefore(iconElement, this.htmlElement.firstChild);
}
}
updateLabel() {
let labelElement = DomHandler.findSingle(this.htmlElement, '.p-button-label');
if (!this.label) {
labelElement && this.htmlElement.removeChild(labelElement);
return;
}
labelElement ? (labelElement.textContent = this.label) : this.createLabel();
}
updateIcon() {
let iconElement = DomHandler.findSingle(this.htmlElement, '.p-button-icon');
let labelElement = DomHandler.findSingle(this.htmlElement, '.p-button-label');
if (iconElement) {
if (this.iconPos) {
iconElement.className = 'p-button-icon ' + (labelElement ? 'p-button-icon-' + this.iconPos : '') + ' ' + this.getIconClass();
}
else {
iconElement.className = 'p-button-icon ' + this.getIconClass();
}
}
else {
this.createIcon();
}
}
getIconClass() {
return this.loading ? 'p-button-loading-icon pi-spin ' + (this.loadingIcon ?? 'pi pi-spinner') : this.icon || 'p-hidden';
}
ngOnDestroy() {
this.initialized = false;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: ButtonDirective, deps: [{ token: i0.ElementRef }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "18.0.1", type: ButtonDirective, isStandalone: true, selector: "[pButton]", inputs: { iconPos: "iconPos", loadingIcon: "loadingIcon", label: "label", icon: "icon", loading: "loading", severity: "severity", raised: ["raised", "raised", booleanAttribute], rounded: ["rounded", "rounded", booleanAttribute], text: ["text", "text", booleanAttribute], outlined: ["outlined", "outlined", booleanAttribute], size: "size", plain: ["plain", "plain", booleanAttribute] }, host: { classAttribute: "p-element" }, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: ButtonDirective, decorators: [{
type: Directive,
args: [{
selector: '[pButton]',
standalone: true,
host: {
class: 'p-element'
}
}]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: Document, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }], propDecorators: { iconPos: [{
type: Input
}], loadingIcon: [{
type: Input
}], label: [{
type: Input
}], icon: [{
type: Input
}], loading: [{
type: Input
}], severity: [{
type: Input
}], raised: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], rounded: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], text: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], outlined: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], size: [{
type: Input
}], plain: [{
type: Input,
args: [{ transform: booleanAttribute }]
}] } });
/**
* Button is an extension to standard button element with icons and theming.
* @group Components
*/
class Button {
el;
/**
* Type of the button.
* @group Props
*/
type = 'button';
/**
* Position of the icon.
* @group Props
*/
iconPos = 'left';
/**
* Name of the icon.
* @group Props
*/
icon;
/**
* Value of the badge.
* @group Props
*/
badge;
/**
* Uses to pass attributes to the label's DOM element.
* @group Props
*/
label;
/**
* When present, it specifies that the component should be disabled.
* @group Props
*/
disabled;
/**
* Whether the button is in loading state.
* @group Props
*/
loading = false;
/**
* Icon to display in loading state.
* @group Props
*/
loadingIcon;
/**
* Add a shadow to indicate elevation.
* @group Props
*/
raised = false;
/**
* Add a circular border radius to the button.
* @group Props
*/
rounded = false;
/**
* Add a textual class to the button without a background initially.
* @group Props
*/
text = false;
/**
* Add a plain textual class to the button without a background initially.
* @group Props
*/
plain = false;
/**
* Defines the style of the button.
* @group Props
*/
severity;
/**
* Add a border class without a background initially.
* @group Props
*/
outlined = false;
/**
* Add a link style to the button.
* @group Props
*/
link = false;
/**
* Add a tabindex to the button.
* @group Props
*/
tabindex;
/**
* Defines the size of the button.
* @group Props
*/
size;
/**
* Inline style of the element.
* @group Props
*/
style;
/**
* Class of the element.
* @group Props
*/
styleClass;
/**
* Style class of the badge.
* @group Props
*/
badgeClass;
/**
* Used to define a string that autocomplete attribute the current element.
* @group Props
*/
ariaLabel;
/**
* When present, it specifies that the component should automatically get focus on load.
* @group Props
*/
autofocus;
/**
* Callback to execute when button is clicked.
* This event is intended to be used with the <p-button> component. Using a regular <button> element, use (click).
* @param {MouseEvent} event - Mouse event.
* @group Emits
*/
onClick = new EventEmitter();
/**
* Callback to execute when button is focused.
* This event is intended to be used with the <p-button> component. Using a regular <button> element, use (focus).
* @param {FocusEvent} event - Focus event.
* @group Emits
*/
onFocus = new EventEmitter();
/**
* Callback to execute when button loses focus.
* This event is intended to be used with the <p-button> component. Using a regular <button> element, use (blur).
* @param {FocusEvent} event - Focus event.
* @group Emits
*/
onBlur = new EventEmitter();
contentTemplate;
loadingIconTemplate;
iconTemplate;
templates;
constructor(el) {
this.el = el;
}
spinnerIconClass() {
return Object.entries(this.iconClass())
.filter(([, value]) => !!value)
.reduce((acc, [key]) => acc + ` ${key}`, 'p-button-loading-icon');
}
iconClass() {
const iconClasses = {
'p-button-icon': true,
'p-button-icon-left': this.iconPos === 'left' && this.label,
'p-button-icon-right': this.iconPos === 'right' && this.label,
'p-button-icon-top': this.iconPos === 'top' && this.label,
'p-button-icon-bottom': this.iconPos === 'bottom' && this.label
};
if (this.loading) {
iconClasses[`p-button-loading-icon pi-spin ${this.loadingIcon ?? ''}`] = true;
}
else if (this.icon) {
iconClasses[this.icon] = true;
}
return iconClasses;
}
get buttonClass() {
return {
'p-button p-component': true,
'p-button-icon-only': (this.icon || this.iconTemplate || this.loadingIcon || this.loadingIconTemplate) && !this.label,
'p-button-vertical': (this.iconPos === 'top' || this.iconPos === 'bottom') && this.label,
'p-button-loading': this.loading,
'p-button-loading-label-only': this.loading && !this.icon && this.label && !this.loadingIcon && this.iconPos === 'left',
'p-button-link': this.link,
[`p-button-${this.severity}`]: this.severity,
'p-button-raised': this.raised,
'p-button-rounded': this.rounded,
'p-button-text': this.text,
'p-button-outlined': this.outlined,
'p-button-sm': this.size === 'small',
'p-button-lg': this.size === 'large',
'p-button-plain': this.plain,
[`${this.styleClass}`]: this.styleClass
};
}
ngAfterContentInit() {
this.templates?.forEach((item) => {
switch (item.getType()) {
case 'content':
this.contentTemplate = item.template;
break;
case 'icon':
this.iconTemplate = item.template;
break;
case 'loadingicon':
this.loadingIconTemplate = item.template;
break;
default:
this.contentTemplate = item.template;
break;
}
});
}
badgeStyleClass() {
return {
'p-badge p-component': true,
'p-badge-no-gutter': this.badge && String(this.badge).length === 1
};
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: Button, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "18.0.1", type: Button, isStandalone: true, selector: "p-button", inputs: { type: "type", iconPos: "iconPos", icon: "icon", badge: "badge", label: "label", disabled: ["disabled", "disabled", booleanAttribute], loading: ["loading", "loading", booleanAttribute], loadingIcon: "loadingIcon", raised: ["raised", "raised", booleanAttribute], rounded: ["rounded", "rounded", booleanAttribute], text: ["text", "text", booleanAttribute], plain: ["plain", "plain", booleanAttribute], severity: "severity", outlined: ["outlined", "outlined", booleanAttribute], link: ["link", "link", booleanAttribute], tabindex: ["tabindex", "tabindex", numberAttribute], size: "size", style: "style", styleClass: "styleClass", badgeClass: "badgeClass", ariaLabel: "ariaLabel", autofocus: ["autofocus", "autofocus", booleanAttribute] }, outputs: { onClick: "onClick", onFocus: "onFocus", onBlur: "onBlur" }, host: { properties: { "class.p-disabled": "disabled" }, classAttribute: "p-element" }, queries: [{ propertyName: "templates", predicate: PrimeTemplate }], ngImport: i0, template: `
<button
[attr.type]="type"
[attr.aria-label]="ariaLabel"
[ngStyle]="style"
[disabled]="disabled || loading"
[ngClass]="buttonClass"
(click)="onClick.emit($event)"
(focus)="onFocus.emit($event)"
(blur)="onBlur.emit($event)"
pRipple
[attr.data-pc-name]="'button'"
[attr.data-pc-section]="'root'"
[attr.tabindex]="tabindex"
pAutoFocus
[autofocus]="autofocus"
>
<ng-content></ng-content>
<ng-container *ngTemplateOutlet="contentTemplate"></ng-container>
<ng-container *ngIf="loading">
<ng-container *ngIf="!loadingIconTemplate">
<span *ngIf="loadingIcon" [ngClass]="iconClass()" [attr.aria-hidden]="true" [attr.data-pc-section]="'loadingicon'"></span>
<SpinnerIcon *ngIf="!loadingIcon" [styleClass]="spinnerIconClass()" [spin]="true" [attr.aria-hidden]="true" [attr.data-pc-section]="'loadingicon'" />
</ng-container>
<ng-template [ngIf]="loadingIconTemplate" *ngTemplateOutlet="loadingIconTemplate; context: { class: iconClass() }"></ng-template>
</ng-container>
<ng-container *ngIf="!loading">
<span *ngIf="icon && !iconTemplate" [ngClass]="iconClass()" [attr.data-pc-section]="'icon'"></span>
<ng-template [ngIf]="!icon && iconTemplate" *ngTemplateOutlet="iconTemplate; context: { class: iconClass() }"></ng-template>
</ng-container>
<span class="p-button-label" [attr.aria-hidden]="icon && !label" *ngIf="!contentTemplate && label" [attr.data-pc-section]="'label'">{{ label }}</span>
<span [ngClass]="badgeStyleClass()" [class]="badgeClass" *ngIf="!contentTemplate && badge" [attr.data-pc-section]="'badge'">{{ badge }}</span>
</button>
`, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: Ripple, selector: "[pRipple]" }, { kind: "directive", type: AutoFocus, selector: "[pAutoFocus]", inputs: ["autofocus"] }, { kind: "component", type: SpinnerIcon, selector: "SpinnerIcon" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: Button, decorators: [{
type: Component,
args: [{
selector: 'p-button',
standalone: true,
imports: [NgIf, NgTemplateOutlet, NgStyle, NgClass, Ripple, AutoFocus, SpinnerIcon],
template: `
<button
[attr.type]="type"
[attr.aria-label]="ariaLabel"
[ngStyle]="style"
[disabled]="disabled || loading"
[ngClass]="buttonClass"
(click)="onClick.emit($event)"
(focus)="onFocus.emit($event)"
(blur)="onBlur.emit($event)"
pRipple
[attr.data-pc-name]="'button'"
[attr.data-pc-section]="'root'"
[attr.tabindex]="tabindex"
pAutoFocus
[autofocus]="autofocus"
>
<ng-content></ng-content>
<ng-container *ngTemplateOutlet="contentTemplate"></ng-container>
<ng-container *ngIf="loading">
<ng-container *ngIf="!loadingIconTemplate">
<span *ngIf="loadingIcon" [ngClass]="iconClass()" [attr.aria-hidden]="true" [attr.data-pc-section]="'loadingicon'"></span>
<SpinnerIcon *ngIf="!loadingIcon" [styleClass]="spinnerIconClass()" [spin]="true" [attr.aria-hidden]="true" [attr.data-pc-section]="'loadingicon'" />
</ng-container>
<ng-template [ngIf]="loadingIconTemplate" *ngTemplateOutlet="loadingIconTemplate; context: { class: iconClass() }"></ng-template>
</ng-container>
<ng-container *ngIf="!loading">
<span *ngIf="icon && !iconTemplate" [ngClass]="iconClass()" [attr.data-pc-section]="'icon'"></span>
<ng-template [ngIf]="!icon && iconTemplate" *ngTemplateOutlet="iconTemplate; context: { class: iconClass() }"></ng-template>
</ng-container>
<span class="p-button-label" [attr.aria-hidden]="icon && !label" *ngIf="!contentTemplate && label" [attr.data-pc-section]="'label'">{{ label }}</span>
<span [ngClass]="badgeStyleClass()" [class]="badgeClass" *ngIf="!contentTemplate && badge" [attr.data-pc-section]="'badge'">{{ badge }}</span>
</button>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
host: {
class: 'p-element',
'[class.p-disabled]': 'disabled' || 'loading'
}
}]
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { type: [{
type: Input
}], iconPos: [{
type: Input
}], icon: [{
type: Input
}], badge: [{
type: Input
}], label: [{
type: Input
}], disabled: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], loading: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], loadingIcon: [{
type: Input
}], raised: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], rounded: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], text: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], plain: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], severity: [{
type: Input
}], outlined: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], link: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], tabindex: [{
type: Input,
args: [{ transform: numberAttribute }]
}], size: [{
type: Input
}], style: [{
type: Input
}], styleClass: [{
type: Input
}], badgeClass: [{
type: Input
}], ariaLabel: [{
type: Input
}], autofocus: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], onClick: [{
type: Output
}], onFocus: [{
type: Output
}], onBlur: [{
type: Output
}], templates: [{
type: ContentChildren,
args: [PrimeTemplate]
}] } });
class ButtonModule {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: ButtonModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.0.1", ngImport: i0, type: ButtonModule, imports: [ButtonDirective, Button], exports: [ButtonDirective, Button, SharedModule] });
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: ButtonModule, imports: [Button, SharedModule] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: ButtonModule, decorators: [{
type: NgModule,
args: [{
imports: [ButtonDirective, Button],
exports: [ButtonDirective, Button, SharedModule]
}]
}] });
/**
* Generated bundle index. Do not edit.
*/
export { Button, ButtonDirective, ButtonModule };
//# sourceMappingURL=primeng-button.mjs.map