{"version":3,"file":"primeng-button.mjs","sources":["../../src/app/components/button/button.ts","../../src/app/components/button/primeng-button.ts"],"sourcesContent":["import { CommonModule, DOCUMENT } from '@angular/common';\nimport {\n AfterContentInit,\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n ContentChildren,\n Directive,\n ElementRef,\n EventEmitter,\n Inject,\n Input,\n NgModule,\n OnDestroy,\n Output,\n QueryList,\n TemplateRef,\n ViewEncapsulation,\n booleanAttribute,\n numberAttribute\n} from '@angular/core';\nimport { PrimeTemplate, SharedModule } from 'primeng/api';\nimport { DomHandler } from 'primeng/dom';\nimport { SpinnerIcon } from 'primeng/icons/spinner';\nimport { RippleModule } from 'primeng/ripple';\nimport { ObjectUtils } from 'primeng/utils';\nimport { AutoFocusModule } from 'primeng/autofocus';\n\ntype ButtonIconPosition = 'left' | 'right' | 'top' | 'bottom';\n\nconst INTERNAL_BUTTON_CLASSES = {\n button: 'p-button',\n component: 'p-component',\n iconOnly: 'p-button-icon-only',\n disabled: 'p-disabled',\n loading: 'p-button-loading',\n labelOnly: 'p-button-loading-label-only'\n} as const;\n/**\n * Button directive is an extension to button component.\n * @group Components\n */\n@Directive({\n selector: '[pButton]',\n host: {\n class: 'p-element'\n }\n})\nexport class ButtonDirective implements AfterViewInit, OnDestroy {\n /**\n * Position of the icon.\n * @group Props\n */\n @Input() iconPos: ButtonIconPosition = 'left';\n /**\n * Uses to pass attributes to the loading icon's DOM element.\n * @group Props\n */\n @Input() loadingIcon: string | undefined;\n /**\n * Text of the button.\n * @group Props\n */\n @Input() get label(): string {\n return this._label as string;\n }\n set label(val: string) {\n this._label = val;\n\n if (this.initialized) {\n this.updateLabel();\n this.updateIcon();\n this.setStyleClass();\n }\n }\n /**\n * Name of the icon.\n * @group Props\n */\n @Input() get icon(): string {\n return this._icon as string;\n }\n set icon(val: string) {\n this._icon = val;\n\n if (this.initialized) {\n this.updateIcon();\n this.setStyleClass();\n }\n }\n /**\n * Whether the button is in loading state.\n * @group Props\n */\n @Input() get loading(): boolean {\n return this._loading;\n }\n set loading(val: boolean) {\n this._loading = val;\n\n if (this.initialized) {\n this.updateIcon();\n this.setStyleClass();\n }\n }\n /**\n * Defines the style of the button.\n * @group Props\n */\n @Input() severity: 'success' | 'info' | 'warning' | 'danger' | 'help' | 'primary' | 'secondary' | 'contrast' | null | undefined;\n /**\n * Add a shadow to indicate elevation.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) raised: boolean = false;\n /**\n * Add a circular border radius to the button.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) rounded: boolean = false;\n /**\n * Add a textual class to the button without a background initially.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) text: boolean = false;\n /**\n * Add a border class without a background initially.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) outlined: boolean = false;\n /**\n * Defines the size of the button.\n * @group Props\n */\n @Input() size: 'small' | 'large' | undefined | null = null;\n /**\n * Add a plain textual class to the button without a background initially.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) plain: boolean = false;\n\n public _label: string | undefined;\n\n public _icon: string | undefined;\n\n public _loading: boolean = false;\n\n public initialized: boolean | undefined;\n\n private get htmlElement(): HTMLElement {\n return this.el.nativeElement as HTMLElement;\n }\n\n private _internalClasses: string[] = Object.values(INTERNAL_BUTTON_CLASSES);\n\n spinnerIcon = ``;\n\n constructor(public el: ElementRef, @Inject(DOCUMENT) private document: Document) {}\n\n ngAfterViewInit() {\n DomHandler.addMultipleClasses(this.htmlElement, this.getStyleClass().join(' '));\n\n this.createIcon();\n this.createLabel();\n\n this.initialized = true;\n }\n\n getStyleClass(): string[] {\n const styleClass: string[] = [INTERNAL_BUTTON_CLASSES.button, INTERNAL_BUTTON_CLASSES.component];\n\n if (this.icon && !this.label && ObjectUtils.isEmpty(this.htmlElement.textContent)) {\n styleClass.push(INTERNAL_BUTTON_CLASSES.iconOnly);\n }\n\n if (this.loading) {\n styleClass.push(INTERNAL_BUTTON_CLASSES.disabled, INTERNAL_BUTTON_CLASSES.loading);\n\n if (!this.icon && this.label) {\n styleClass.push(INTERNAL_BUTTON_CLASSES.labelOnly);\n }\n\n if (this.icon && !this.label && !ObjectUtils.isEmpty(this.htmlElement.textContent)) {\n styleClass.push(INTERNAL_BUTTON_CLASSES.iconOnly);\n }\n }\n\n if (this.text) {\n styleClass.push('p-button-text');\n }\n\n if (this.severity) {\n styleClass.push(`p-button-${this.severity}`);\n }\n\n if (this.plain) {\n styleClass.push('p-button-plain');\n }\n\n if (this.raised) {\n styleClass.push('p-button-raised');\n }\n\n if (this.size) {\n styleClass.push(`p-button-${this.size}`);\n }\n\n if (this.outlined) {\n styleClass.push('p-button-outlined');\n }\n\n if (this.rounded) {\n styleClass.push('p-button-rounded');\n }\n\n if (this.size === 'small') {\n styleClass.push('p-button-sm');\n }\n\n if (this.size === 'large') {\n styleClass.push('p-button-lg');\n }\n\n return styleClass;\n }\n\n setStyleClass() {\n const styleClass = this.getStyleClass();\n this.htmlElement.classList.remove(...this._internalClasses);\n this.htmlElement.classList.add(...styleClass);\n }\n\n createLabel() {\n const created = DomHandler.findSingle(this.htmlElement, '.p-button-label');\n if (!created && this.label) {\n let labelElement = this.document.createElement('span');\n if (this.icon && !this.label) {\n labelElement.setAttribute('aria-hidden', 'true');\n }\n\n labelElement.className = 'p-button-label';\n labelElement.appendChild(this.document.createTextNode(this.label));\n\n this.htmlElement.appendChild(labelElement);\n }\n }\n\n createIcon() {\n const created = DomHandler.findSingle(this.htmlElement, '.p-button-icon');\n if (!created && (this.icon || this.loading)) {\n let iconElement = this.document.createElement('span');\n iconElement.className = 'p-button-icon';\n iconElement.setAttribute('aria-hidden', 'true');\n let iconPosClass = this.label ? 'p-button-icon-' + this.iconPos : null;\n\n if (iconPosClass) {\n DomHandler.addClass(iconElement, iconPosClass);\n }\n\n let iconClass = this.getIconClass();\n\n if (iconClass) {\n DomHandler.addMultipleClasses(iconElement, iconClass);\n }\n\n if (!this.loadingIcon && this.loading) {\n iconElement.innerHTML = this.spinnerIcon;\n }\n\n this.htmlElement.insertBefore(iconElement, this.htmlElement.firstChild);\n }\n }\n\n updateLabel() {\n let labelElement = DomHandler.findSingle(this.htmlElement, '.p-button-label');\n\n if (!this.label) {\n labelElement && this.htmlElement.removeChild(labelElement);\n return;\n }\n\n labelElement ? (labelElement.textContent = this.label) : this.createLabel();\n }\n\n updateIcon() {\n let iconElement = DomHandler.findSingle(this.htmlElement, '.p-button-icon');\n let labelElement = DomHandler.findSingle(this.htmlElement, '.p-button-label');\n\n if (this.loading && !this.loadingIcon && iconElement) {\n iconElement.innerHTML = this.spinnerIcon;\n } else if (iconElement?.innerHTML) {\n iconElement.innerHTML = '';\n }\n\n if (iconElement) {\n if (this.iconPos) {\n iconElement.className = 'p-button-icon ' + (labelElement ? 'p-button-icon-' + this.iconPos : '') + ' ' + this.getIconClass();\n } else {\n iconElement.className = 'p-button-icon ' + this.getIconClass();\n }\n } else {\n this.createIcon();\n }\n }\n\n getIconClass() {\n return this.loading ? 'p-button-loading-icon ' + (this.loadingIcon ? this.loadingIcon : 'p-icon') : this.icon || 'p-hidden';\n }\n\n ngOnDestroy() {\n this.initialized = false;\n }\n}\n/**\n * Button is an extension to standard button element with icons and theming.\n * @group Components\n */\n@Component({\n selector: 'p-button',\n template: `\n \n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'p-element',\n '[class.p-disabled]': 'disabled' || 'loading'\n }\n})\nexport class Button implements AfterContentInit {\n /**\n * Type of the button.\n * @group Props\n */\n @Input() type: string = 'button';\n /**\n * Position of the icon.\n * @group Props\n */\n @Input() iconPos: ButtonIconPosition = 'left';\n /**\n * Name of the icon.\n * @group Props\n */\n @Input() icon: string | undefined;\n /**\n * Value of the badge.\n * @group Props\n */\n @Input() badge: string | undefined;\n /**\n * Uses to pass attributes to the label's DOM element.\n * @group Props\n */\n @Input() label: string | undefined;\n /**\n * When present, it specifies that the component should be disabled.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) disabled: boolean | undefined;\n /**\n * Whether the button is in loading state.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) loading: boolean = false;\n /**\n * Icon to display in loading state.\n * @group Props\n */\n @Input() loadingIcon: string | undefined;\n /**\n * Add a shadow to indicate elevation.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) raised: boolean = false;\n /**\n * Add a circular border radius to the button.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) rounded: boolean = false;\n /**\n * Add a textual class to the button without a background initially.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) text: boolean = false;\n /**\n * Add a plain textual class to the button without a background initially.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) plain: boolean = false;\n /**\n * Defines the style of the button.\n * @group Props\n */\n @Input() severity: 'success' | 'info' | 'warning' | 'danger' | 'help' | 'primary' | 'secondary' | 'contrast' | null | undefined;\n /**\n * Add a border class without a background initially.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) outlined: boolean = false;\n /**\n * Add a link style to the button.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) link: boolean = false;\n /**\n * Add a tabindex to the button.\n * @group Props\n */\n @Input({ transform: numberAttribute }) tabindex: number | undefined;\n /**\n * Defines the size of the button.\n * @group Props\n */\n @Input() size: 'small' | 'large' | undefined;\n /**\n * Inline style of the element.\n * @group Props\n */\n @Input() style: { [klass: string]: any } | null | undefined;\n /**\n * Class of the element.\n * @group Props\n */\n @Input() styleClass: string | undefined;\n /**\n * Style class of the badge.\n * @group Props\n */\n @Input() badgeClass: string | undefined;\n /**\n * Used to define a string that autocomplete attribute the current element.\n * @group Props\n */\n @Input() ariaLabel: string | undefined;\n /**\n * When present, it specifies that the component should automatically get focus on load.\n * @group Props\n */\n @Input({ transform: booleanAttribute }) autofocus: boolean | undefined;\n /**\n * Callback to execute when button is clicked.\n * This event is intended to be used with the component. Using a regular