diff --git a/src/app/components/badge/badge.ts b/src/app/components/badge/badge.ts
index df9cae7a047..583e86179d1 100755
--- a/src/app/components/badge/badge.ts
+++ b/src/app/components/badge/badge.ts
@@ -1,5 +1,5 @@
import { CommonModule, DOCUMENT } from '@angular/common';
-import { AfterViewInit, ChangeDetectionStrategy, Component, Directive, ElementRef, Inject, Input, NgModule, OnDestroy, Renderer2, ViewEncapsulation, booleanAttribute } from '@angular/core';
+import { AfterViewInit, ChangeDetectionStrategy, Component, Directive, ElementRef, Inject, Input, NgModule, Renderer2, OnChanges, SimpleChanges, ViewEncapsulation, booleanAttribute } from '@angular/core';
import { SharedModule } from 'primeng/api';
import { DomHandler } from 'primeng/dom';
import { UniqueComponentId } from 'primeng/utils';
@@ -13,117 +13,95 @@ import { UniqueComponentId } from 'primeng/utils';
class: 'p-element'
}
})
-export class BadgeDirective implements AfterViewInit, OnDestroy {
- /**
- * Icon position of the component.
- * @group Props
- */
- @Input() iconPos: 'left' | 'right' | 'top' | 'bottom' = 'left';
+export class BadgeDirective implements OnChanges, AfterViewInit {
/**
* When specified, disables the component.
* @group Props
*/
- @Input('badgeDisabled') get disabled(): boolean {
- return this._disabled;
- }
- set disabled(val: boolean) {
- this._disabled = val;
- }
+ @Input('badgeDisabled') public disabled: boolean;
/**
* Size of the badge, valid options are "large" and "xlarge".
* @group Props
*/
- @Input() public get size(): 'large' | 'xlarge' {
- return this._size;
- }
- set size(val: 'large' | 'xlarge') {
- this._size = val;
-
- if (this.initialized) {
- this.setSizeClasses();
- }
- }
+ @Input() public badgeSize: 'large' | 'xlarge';
/**
- * Value to display inside the badge.
+ * Severity type of the badge.
* @group Props
*/
- @Input() get value(): string {
- return this._value;
- }
- set value(val: string) {
- if (val !== this._value) {
- this._value = val;
-
- if (this.initialized) {
- let badge: HTMLElement = document.getElementById(this.id) as HTMLElement;
-
- if (this._value) {
- if (DomHandler.hasClass(badge, 'p-badge-dot')) DomHandler.removeClass(badge, 'p-badge-dot');
-
- if (String(this._value).length === 1) {
- DomHandler.addClass(badge, 'p-badge-no-gutter');
- } else {
- DomHandler.removeClass(badge, 'p-badge-no-gutter');
- }
- } else if (!this._value && !DomHandler.hasClass(badge, 'p-badge-dot')) {
- DomHandler.addClass(badge, 'p-badge-dot');
- }
-
- badge.innerHTML = '';
- this.renderer.appendChild(badge, document.createTextNode(this._value));
- }
- }
- }
+ @Input() public severity: 'success' | 'info' | 'warning' | 'danger' | null | undefined;
/**
- * Severity type of the badge.
+ * Value to display inside the badge.
* @group Props
*/
- @Input() severity: 'success' | 'info' | 'warning' | 'danger' | null | undefined;
-
- public _value!: string;
-
- public initialized: boolean = false;
+ @Input() public value: string | number;
private id!: string;
- private _disabled: boolean = false;
+ private get activeElement(): HTMLElement {
+ return this.el.nativeElement.nodeName.indexOf('-') != -1 ? this.el.nativeElement.firstChild : this.el.nativeElement;
+ }
- private _size!: 'large' | 'xlarge';
+ private get canUpdateBadge(): boolean {
+ return this.id && !this.disabled;
+ }
constructor(@Inject(DOCUMENT) private document: Document, public el: ElementRef, private renderer: Renderer2) {}
- ngAfterViewInit() {
- this.id = UniqueComponentId() + '_badge';
- let el = this.el.nativeElement.nodeName.indexOf('-') != -1 ? this.el.nativeElement.firstChild : this.el.nativeElement;
+ public ngOnChanges({ value, size, severity, disabled }: SimpleChanges): void {
+ if (disabled) {
+ this.toggleDisableState();
+ }
- if (this._disabled) {
- return null;
+ if (!this.canUpdateBadge) {
+ return;
}
- let badge = this.document.createElement('span');
- badge.id = this.id;
- badge.className = 'p-badge p-component';
+ if (severity) {
+ this.setSeverity(severity.previousValue);
+ }
- if (this.severity) {
- DomHandler.addClass(badge, 'p-badge-' + this.severity);
+ if (size) {
+ this.setSizeClasses();
}
- this.setSizeClasses(badge);
+ if (value) {
+ this.setValue();
+ }
+ }
+
+ public ngAfterViewInit(): void {
+ this.id = UniqueComponentId() + '_badge';
+ this.renderBadgeContent();
+ }
+
+ private setValue(element?: HTMLElement): void {
+ const badge = element ?? this.document.getElementById(this.id);
+
+ if (!badge) {
+ return;
+ }
if (this.value != null) {
- this.renderer.appendChild(badge, this.document.createTextNode(this.value));
+ if (DomHandler.hasClass(badge, 'p-badge-dot')) {
+ DomHandler.removeClass(badge, 'p-badge-dot');
+ }
- if (String(this.value).length === 1) {
+ if (this.value && String(this.value).length === 1) {
DomHandler.addClass(badge, 'p-badge-no-gutter');
+ } else {
+ DomHandler.removeClass(badge, 'p-badge-no-gutter');
}
} else {
- DomHandler.addClass(badge, 'p-badge-dot');
- }
+ if (!DomHandler.hasClass(badge, 'p-badge-dot')) {
+ DomHandler.addClass(badge, 'p-badge-dot');
+ }
- DomHandler.addClass(el, 'p-overlay-badge');
- this.renderer.appendChild(el, badge);
+ DomHandler.removeClass(badge, 'p-badge-no-gutter');
+ }
- this.initialized = true;
+ badge.innerHTML = '';
+ const badgeValue = this.value != null ? String(this.value) : '';
+ this.renderer.appendChild(badge, this.document.createTextNode(badgeValue));
}
private setSizeClasses(element?: HTMLElement): void {
@@ -133,13 +111,13 @@ export class BadgeDirective implements AfterViewInit, OnDestroy {
return;
}
- if (this._size) {
- if (this._size === 'large') {
+ if (this.badgeSize) {
+ if (this.badgeSize === 'large') {
DomHandler.addClass(badge, 'p-badge-lg');
DomHandler.removeClass(badge, 'p-badge-xl');
}
- if (this._size === 'xlarge') {
+ if (this.badgeSize === 'xlarge') {
DomHandler.addClass(badge, 'p-badge-xl');
DomHandler.removeClass(badge, 'p-badge-lg');
}
@@ -149,8 +127,53 @@ export class BadgeDirective implements AfterViewInit, OnDestroy {
}
}
- ngOnDestroy() {
- this.initialized = false;
+ private renderBadgeContent(): void {
+ if (this.disabled) {
+ return null;
+ }
+
+ const el = this.activeElement;
+ const badge = this.document.createElement('span');
+ badge.id = this.id;
+ badge.className = 'p-badge p-component';
+
+ this.setSeverity(null, badge);
+ this.setSizeClasses(badge);
+ this.setValue(badge);
+ DomHandler.addClass(el, 'p-overlay-badge');
+ this.renderer.appendChild(el, badge);
+ }
+
+ private setSeverity(oldSeverity?: 'success' | 'info' | 'warning' | 'danger' | null, element?: HTMLElement): void {
+ const badge = element ?? this.document.getElementById(this.id);
+
+ if (!badge) {
+ return;
+ }
+
+ if (this.severity) {
+ DomHandler.addClass(badge, `p-badge-${this.severity}`);
+ }
+
+ if (oldSeverity) {
+ DomHandler.removeClass(badge, `p-badge-${oldSeverity}`);
+ }
+ }
+
+ private toggleDisableState(): void {
+ if (!this.id) {
+ return;
+ }
+
+ if (this.disabled) {
+ const badge = this.activeElement?.querySelector(`#${this.id}`);
+
+ if (badge) {
+ this.renderer.removeChild(this.activeElement, badge);
+ }
+ } else {
+ this.renderBadgeContent();
+ }
}
}
/**
@@ -182,7 +205,7 @@ export class Badge {
* Size of the badge, valid options are "large" and "xlarge".
* @group Props
*/
- @Input() size: 'large' | 'xlarge' | undefined;
+ @Input() badgeSize: 'large' | 'xlarge' | undefined;
/**
* Severity type of the badge.
* @group Props
@@ -192,7 +215,7 @@ export class Badge {
* Value to display inside the badge.
* @group Props
*/
- @Input() value: string | null | undefined;
+ @Input() value: string | number | null | undefined;
/**
* When specified, disables the component.
* @group Props
@@ -203,8 +226,8 @@ export class Badge {
return {
'p-badge p-component': true,
'p-badge-no-gutter': this.value != undefined && String(this.value).length === 1,
- 'p-badge-lg': this.size === 'large',
- 'p-badge-xl': this.size === 'xlarge',
+ 'p-badge-lg': this.badgeSize === 'large',
+ 'p-badge-xl': this.badgeSize === 'xlarge',
'p-badge-info': this.severity === 'info',
'p-badge-success': this.severity === 'success',
'p-badge-warning': this.severity === 'warning',
diff --git a/src/app/showcase/doc/apidoc/index.json b/src/app/showcase/doc/apidoc/index.json
index a2ccdbba80f..755a5317b33 100644
--- a/src/app/showcase/doc/apidoc/index.json
+++ b/src/app/showcase/doc/apidoc/index.json
@@ -4455,41 +4455,34 @@
"props": {
"description": "Defines the input properties of the component.",
"values": [
- {
- "name": "iconPos",
- "optional": false,
- "readonly": false,
- "type": "\"left\" | \"top\" | \"bottom\" | \"right\"",
- "default": "left",
- "description": "Icon position of the component."
- },
{
"name": "disabled",
"optional": false,
"readonly": false,
"type": "boolean",
+ "default": "false",
"description": "When specified, disables the component."
},
{
- "name": "size",
+ "name": "badgeSize",
"optional": false,
"readonly": false,
"type": "\"large\" | \"xlarge\"",
"description": "Size of the badge, valid options are \"large\" and \"xlarge\"."
},
{
- "name": "value",
+ "name": "severity",
"optional": false,
"readonly": false,
- "type": "string",
- "description": "Value to display inside the badge."
+ "type": "\"success\" | \"info\" | \"warning\" | \"danger\"",
+ "description": "Severity type of the badge."
},
{
- "name": "severity",
+ "name": "value",
"optional": false,
"readonly": false,
- "type": "\"success\" | \"info\" | \"warning\" | \"danger\"",
- "description": "Severity type of the badge."
+ "type": "string | number",
+ "description": "Value to display inside the badge."
}
]
}
@@ -4514,7 +4507,7 @@
"description": "Inline style of the element."
},
{
- "name": "size",
+ "name": "badgeSize",
"optional": false,
"readonly": false,
"type": "\"large\" | \"xlarge\"",
@@ -4531,7 +4524,7 @@
"name": "value",
"optional": false,
"readonly": false,
- "type": "string",
+ "type": "string | number",
"description": "Value to display inside the badge."
},
{
diff --git a/src/app/showcase/doc/badge/sizedoc.ts b/src/app/showcase/doc/badge/sizedoc.ts
index d9f8a5bb498..905445f1a0d 100644
--- a/src/app/showcase/doc/badge/sizedoc.ts
+++ b/src/app/showcase/doc/badge/sizedoc.ts
@@ -5,24 +5,24 @@ import { Code } from '../../domain/code';
selector: 'badge-size-demo',
template: `
Badge sizes are adjusted with the size property that accepts large and xlarge as the possible alternatives to the default size. Currently sizes only apply to component mode. Badge sizes are adjusted with the badgeSize property that accepts large and xlarge as the possible alternatives to the default size. Currently sizes only apply to component mode.