From 5410ef4ab510208c539279fab33cae5efb6dcf71 Mon Sep 17 00:00:00 2001 From: anliben Date: Fri, 24 Nov 2023 13:07:57 -0300 Subject: [PATCH] =?UTF-8?q?feat(badge):=20implementa=20defini=C3=A7=C3=B5e?= =?UTF-8?q?s=20do=20AnimaliaDS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit implementa definições do AnimaliaDS no componente `po-badge` Fixes DTHFUI-7933 --- .../src/lib/components/components.module.ts | 7 +- projects/ui/src/lib/components/index.ts | 1 + .../interfaces/po-badge-literals-default.ts | 18 ++ .../interfaces/po-badge-literals.interface.ts | 14 ++ .../po-badge/po-badge-base.component.spec.ts | 74 ++++---- .../po-badge/po-badge-base.component.ts | 177 ++++++++++++----- .../po-badge/po-badge.component.html | 15 +- .../po-badge/po-badge.component.spec.ts | 178 +++++++++++++----- .../components/po-badge/po-badge.component.ts | 138 +++++++++++++- .../components/po-badge/po-badge.module.ts | 3 +- .../sample-po-badge-basic.component.html | 1 + .../sample-po-badge-basic.component.ts | 7 + .../sample-po-badge-labs.component.html | 64 +++++++ .../sample-po-badge-labs.component.ts | 69 +++++++ .../sample-po-badge-message.component.css | 41 ++++ .../sample-po-badge-message.component.html | 19 ++ .../sample-po-badge-message.component.ts | 23 +++ 17 files changed, 709 insertions(+), 140 deletions(-) create mode 100644 projects/ui/src/lib/components/po-badge/interfaces/po-badge-literals-default.ts create mode 100644 projects/ui/src/lib/components/po-badge/interfaces/po-badge-literals.interface.ts create mode 100644 projects/ui/src/lib/components/po-badge/samples/sample-po-badge-basic/sample-po-badge-basic.component.html create mode 100644 projects/ui/src/lib/components/po-badge/samples/sample-po-badge-basic/sample-po-badge-basic.component.ts create mode 100644 projects/ui/src/lib/components/po-badge/samples/sample-po-badge-labs/sample-po-badge-labs.component.html create mode 100644 projects/ui/src/lib/components/po-badge/samples/sample-po-badge-labs/sample-po-badge-labs.component.ts create mode 100644 projects/ui/src/lib/components/po-badge/samples/sample-po-badge-message/sample-po-badge-message.component.css create mode 100644 projects/ui/src/lib/components/po-badge/samples/sample-po-badge-message/sample-po-badge-message.component.html create mode 100644 projects/ui/src/lib/components/po-badge/samples/sample-po-badge-message/sample-po-badge-message.component.ts diff --git a/projects/ui/src/lib/components/components.module.ts b/projects/ui/src/lib/components/components.module.ts index fc4b30f23..458ac256d 100644 --- a/projects/ui/src/lib/components/components.module.ts +++ b/projects/ui/src/lib/components/components.module.ts @@ -45,6 +45,7 @@ import { PoToolbarModule } from './po-toolbar/po-toolbar.module'; import { PoTreeViewModule } from './po-tree-view/po-tree-view.module'; import { PoWidgetModule } from './po-widget/po-widget.module'; import { PoSearchModule } from './po-search'; +import { PoBadgeModule } from './po-badge/po-badge.module'; @NgModule({ imports: [ @@ -92,7 +93,8 @@ import { PoSearchModule } from './po-search'; PoImageModule, PoPageSlideModule, PoSwitchModule, - PoSearchModule + PoSearchModule, + PoBadgeModule ], exports: [ PoAccordionModule, @@ -139,7 +141,8 @@ import { PoSearchModule } from './po-search'; PoImageModule, PoPageSlideModule, PoSwitchModule, - PoSearchModule + PoSearchModule, + PoBadgeModule ], providers: [], bootstrap: [], diff --git a/projects/ui/src/lib/components/index.ts b/projects/ui/src/lib/components/index.ts index 4e73e4128..1f6a92cbf 100644 --- a/projects/ui/src/lib/components/index.ts +++ b/projects/ui/src/lib/components/index.ts @@ -2,6 +2,7 @@ export * from './components.module'; export * from './po-accordion/index'; export * from './po-avatar/index'; +export * from './po-badge/index'; export * from './po-breadcrumb/index'; export * from './po-button-group/index'; export * from './po-button/index'; diff --git a/projects/ui/src/lib/components/po-badge/interfaces/po-badge-literals-default.ts b/projects/ui/src/lib/components/po-badge/interfaces/po-badge-literals-default.ts new file mode 100644 index 000000000..dd4b47551 --- /dev/null +++ b/projects/ui/src/lib/components/po-badge/interfaces/po-badge-literals-default.ts @@ -0,0 +1,18 @@ +export const PoBadgeLiteralsDefault = { + en: { + notification: 'new notification', + notifications: 'new notifications' + }, + es: { + notification: 'nueva notificación', + notifications: 'nuevas notificaciones' + }, + pt: { + notification: 'nova notificação', + notifications: 'nova notificaçoes' + }, + ru: { + notification: 'новое уведомление', + notifications: 'новые уведомления' + } +}; diff --git a/projects/ui/src/lib/components/po-badge/interfaces/po-badge-literals.interface.ts b/projects/ui/src/lib/components/po-badge/interfaces/po-badge-literals.interface.ts new file mode 100644 index 000000000..910c60359 --- /dev/null +++ b/projects/ui/src/lib/components/po-badge/interfaces/po-badge-literals.interface.ts @@ -0,0 +1,14 @@ +/** + * @usedBy PoBadgeComponent + * + * @description + * + * Interface para definição das literais usadas no `po-badge`. + */ +export interface PoBadgeLiterals { + /** Texto exibido na propriedade `aria-label` do `po-badge` ao ter somente uma notificação. */ + notification: string; + + /** Texto exibido na propriedade `aria-label` do `po-badge` ao ter mais de uma notificação. */ + notifications: string; +} diff --git a/projects/ui/src/lib/components/po-badge/po-badge-base.component.spec.ts b/projects/ui/src/lib/components/po-badge/po-badge-base.component.spec.ts index 78ec8c163..abf557135 100644 --- a/projects/ui/src/lib/components/po-badge/po-badge-base.component.spec.ts +++ b/projects/ui/src/lib/components/po-badge/po-badge-base.component.spec.ts @@ -10,66 +10,72 @@ describe('PoBadgeBaseComponent:', () => { }); describe('Properties:', () => { - it('p-color: should update with valid values', () => { - const validValues = ['color-01', 'color-02', 'color-03', 'color-04', 'color-12', 'color-08']; + it('p-area-label: set areaLabel with empty when value equals undefined', () => { + component.areaLabel = undefined; - expectPropertiesValues(component, 'color', validValues, validValues); + expect(component.areaLabel).toBe(undefined); }); - it('p-color: should update with invalid values', () => { - const invalidValues = [true, false, undefined, 'color-13', 'color-100', 'color-8', [], {}, null, 0]; + it('p-area-label: set areaLabel with value passed', () => { + component.areaLabel = 'Notification'; - expectPropertiesValues(component, 'color', invalidValues, 'color-07'); + expect(component.areaLabel).toBe('Notification'); }); - it('p-value: should update with valid values and call `setBadgeValue`', () => { - const validValues = [10, 200, 50, 0, 999]; - - spyOn(component, 'setBadgeValue'); + it('p-color: should update with valid values', () => { + component.color = 'color-09'; - expectPropertiesValues(component, 'value', validValues, validValues); - expect(component['setBadgeValue']).toHaveBeenCalled(); + expect(component['_color']).toBe('color-09'); }); - it('p-value: should update with invalid values and call `setBadgeValue`', () => { - const invalidValues = [true, false, undefined, 'string', [], {}, null]; + it('p-color: should update with invalid values and set value default `color-07`', () => { + component.color = 'color-13'; + + expect(component['_color']).toBe('color-07'); + }); - spyOn(component, 'setBadgeValue'); + it('customColor: should update with valid values', () => { + const validValues = ['#ffffff', 'red', 'rgb(201, 53, 125)']; - expectPropertiesValues(component, 'value', invalidValues, undefined); - expect(component['setBadgeValue']).toHaveBeenCalled(); + expectPropertiesValues(component, 'customColor', validValues, validValues); }); - }); - describe('Methods:', () => { - it(`setBadgeValue: should set 'badgeValue' with 'undefined' if value is 'undefined'`, () => { - component['setBadgeValue'](undefined); + it('customColor: should update with valid values and HEX', () => { + component.color = '#fff'; - expect(component.badgeValue).toBe(undefined); + expect(component.customColor).toBe('#fff'); }); - it(`setBadgeValue: should set 'badgeValue' with '99+' if value is greater than '99'`, () => { - component['setBadgeValue'](100); + it('p-value: should update with valid values', () => { + const validValues = [10, 200, 50, 0, 999]; - expect(component.badgeValue).toBe('99+'); + expectPropertiesValues(component, 'value', validValues, validValues); }); - it(`setBadgeValue: should set 'badgeValue' with '55' if value is '55'`, () => { - component['setBadgeValue'](55); + it('p-value: should update with invalid values', () => { + const validValues = [-1, -20, -30]; - expect(component.badgeValue).toBe('55'); + expectPropertiesValues(component, 'value', validValues, 0); }); - it(`setBadgeValue: should set 'badgeValue' with '0' if value is '0'`, () => { - component['setBadgeValue'](0); + it('p-icon: should set icon when value if isnt null', () => { + const iconFake = 'po-icon-minus'; + component.icon = iconFake; + expect(component.icon).toBe(iconFake); + }); - expect(component.badgeValue).toBe('0'); + it('p-icon: should set icon undefined when value if null', () => { + const iconFake = undefined; + component.icon = iconFake; + expect(component.icon).toBe(undefined); }); - it(`setBadgeValue: should set 'badgeValue' with '99' if value is '99'`, () => { - component['setBadgeValue'](99); + it(`setSize: should set 'size' with 'large' if value is 'large'`, () => { + const newSize = 'large'; + + component.size = newSize; - expect(component.badgeValue).toBe('99'); + expect(component['size']).toBe(newSize); }); }); }); diff --git a/projects/ui/src/lib/components/po-badge/po-badge-base.component.ts b/projects/ui/src/lib/components/po-badge/po-badge-base.component.ts index 642a3edea..e8c6e230f 100644 --- a/projects/ui/src/lib/components/po-badge/po-badge-base.component.ts +++ b/projects/ui/src/lib/components/po-badge/po-badge-base.component.ts @@ -1,94 +1,167 @@ -import { Input, Directive } from '@angular/core'; +import { Input, Directive, TemplateRef, HostBinding } from '@angular/core'; -import { convertToInt } from '../../utils/util'; +import { convertToBoolean, convertToInt } from '../../utils/util'; +import { PoColorPaletteEnum } from '../../enums/po-color-palette.enum'; -const PO_BADGE_COLORS = [ - 'color-01', - 'color-02', - 'color-03', - 'color-04', - 'color-05', - 'color-06', - 'color-07', - 'color-08', - 'color-09', - 'color-10', - 'color-11', - 'color-12' -]; +const poBadgeColors = (Object).values(PoColorPaletteEnum); const PO_BADGE_COLOR_DEFAULT = 'color-07'; +export type PoBadgeStatus = 'disabled' | 'negative' | 'positive' | 'warning'; +export type PoBadgeSize = 'small' | 'medium' | 'large'; +export type PoBadgeIcon = string | boolean | TemplateRef; /** * @description * - * @docsPrivate - * - * Componente utilizado no `po-menu` para exibir por exemplo a quantidade de tarefas pendentes. + * Utilizado para exibir a quantidade de notificações. */ @Directive() export class PoBadgeBaseComponent { badgeValue: string; + customColor: string; - private _color: string; + private _color: string = PO_BADGE_COLOR_DEFAULT; private _value: number; + private _status?: PoBadgeStatus; + private _areaLabel: string; /** - * @optional - * * @description * - * Define a cor de fundo do componente e aceita os valores: - * - * `color-01` + * Define um `aria-label` para o `po-badge` + */ + @Input('p-area-label') set areaLabel(value: string) { + if (value === undefined) { + this._areaLabel = ''; + } + this._areaLabel = value; + } + + get areaLabel(): string { + return this._areaLabel; + } + + /** + * @optional * - * `color-02` + * @description * - * `color-03` + * Determina a cor do `po-badge`. As maneiras de customizar as cores são: + * - Hexadeximal, por exemplo `#c64840`; + * - RGB, como `rgb(0, 0, 165)`; + * - O nome da cor, por exemplo `blue`; + * - Usando uma das cores do tema do PO: + * Valores válidos: + * - `color-01` + * - `color-02` + * - `color-03` + * - `color-04` + * - `color-05` + * - `color-06` + * - `color-07` + * - `color-08` + * - `color-09` + * - `color-10` + * - `color-11` + * - `color-12` * - * `color-04` + * @default `color-07` + */ + @Input('p-color') set color(value: string) { + if (value !== undefined && value.includes('color')) { + this._color = poBadgeColors.includes(value) ? value : PO_BADGE_COLOR_DEFAULT; + } else { + CSS.supports('background-color', value) ? (this.customColor = value) : (this.customColor = undefined); + } + } + + get color(): string { + return this._color; + } + + /** + * @optional * - * `color-05` + * @description + * Ícone exibido no `po-badge`. + * + * Para exibir icone do status atual declare a propriedade `p-icon`. conforme exemplo abaixo: + * ``` + * + * ``` + * É possível usar qualquer um dos ícones da [Biblioteca de ícones](/guides/icons). conforme exemplo abaixo: + * ``` + * + * ``` + * Também é possível utilizar outras fontes de ícones, por exemplo a biblioteca *Font Awesome*, da seguinte forma: + * ``` + * + * ``` + * Outra opção seria a customização do ícone através do `TemplateRef`, conforme exemplo abaixo: + * ``` + * + * + * + * + * + * ``` + */ + @Input('p-icon') icon: PoBadgeIcon; + + /** + * @description * - * `color-06` + * Define o estado do `po-badge` * - * `color-07` + * Valores válidos: + * - `positive`: Define a cor do `po-badge` com a cor de feedback positivo.; + * - `negative`: Define a cor do `po-badge` com a cor de feedback negative.; + * - `warning`: Define a cor do `po-badge` com a cor de feedback warning.; + * - `disabled`: Define a cor do `po-badge` com a cor de feedback disabled; * - * `color-08` + */ + @HostBinding('attr.p-status') + @Input('p-status') + set status(value: PoBadgeStatus) { + this._status = ['positive', 'negative', 'warning', 'disabled'].includes(value) ? value : undefined; + } + + get status(): PoBadgeStatus { + return this._status; + } + + /** + * @description * - * `color-09` + * Define o tamanho do `po-badge` * - * `color-10` + * Valores válidos: + * - `small`: o `po-badge` fica do tamanho padrão, com 8px de altura.; + * - `medium`: o `po-badge` fica do tamanho padrão, com 16px de altura.; + * - `large`: o `po-badge` fica do tamanho padrão, com 24px de altura.; * - * `color-11` + * @default `medium` + */ + @Input('p-size') size: PoBadgeSize = 'medium'; + + /** + * @description * - * `color-12` + * Exibe uma borda para o `po-badge` * - * @default `color-07` + * > Pode personalizar cor da bordar com a propriedade `p-color-border` */ - @Input('p-color') set color(value: string) { - this._color = PO_BADGE_COLORS.includes(value) ? value : PO_BADGE_COLOR_DEFAULT; - } - - get color(): string { - return this._color; - } + @Input({ alias: 'p-show-border', transform: convertToBoolean }) showBorder: boolean = false; /** * @description * - * Número exibido no componente, caso o mesmo seja maior que 99 o valor exibido será 99+. + * Número exibido no componente, caso o mesmo seja maior que 9 o valor exibido será 9+. */ @Input('p-value') set value(value: number) { - this._value = convertToInt(value); - this.setBadgeValue(this._value); + this._value = value <= 0 ? 0 : convertToInt(value); } get value(): number { return this._value; } - - private setBadgeValue(value: number) { - const validRangeValue = (value || value === 0) && value >= 0 && value < 100; - this.badgeValue = validRangeValue ? value.toString() : value > 99 ? '99+' : undefined; - } } diff --git a/projects/ui/src/lib/components/po-badge/po-badge.component.html b/projects/ui/src/lib/components/po-badge/po-badge.component.html index f49e8ac19..75af6b1fd 100644 --- a/projects/ui/src/lib/components/po-badge/po-badge.component.html +++ b/projects/ui/src/lib/components/po-badge/po-badge.component.html @@ -1,3 +1,14 @@ -
- {{ badgeValue }} +
+ +
diff --git a/projects/ui/src/lib/components/po-badge/po-badge.component.spec.ts b/projects/ui/src/lib/components/po-badge/po-badge.component.spec.ts index 9c406249b..09f58ed0d 100644 --- a/projects/ui/src/lib/components/po-badge/po-badge.component.spec.ts +++ b/projects/ui/src/lib/components/po-badge/po-badge.component.spec.ts @@ -25,85 +25,173 @@ describe('PoBadgeComponent:', () => { expect(component instanceof PoBadgeComponent).toBeTruthy(); }); - describe('Templates:', () => { - const badgeColorDefaultSelector = '.po-badge.po-color-07'; - const badgeValueSelector = '.po-badge-value'; + describe('Methods:', () => { + it('setStatus: should call setStatus when "status" changes', () => { + const changesFake = { status: 'status' }; + spyOn(component, 'setStatus'); - it('should create `po-badge` with value `55` if `value` is `55`', () => { - const result = '55'; - component.value = 55; + component.ngOnChanges(changesFake); - fixture.detectChanges(); + expect(component.setStatus).toHaveBeenCalled(); + }); + + it('getChangeStyle: should return `po-badge-default`', () => { + component.status = 'positive'; - const badgeValue = fixture.nativeElement.querySelector(badgeValueSelector); + const getChangeStyle = component.getChangeStyle(); - expect(badgeValue.innerHTML).toBe(result); + expect(getChangeStyle).toEqual('po-badge-default'); }); - it('should create `po-badge` with value `0` if `value` is `0`', () => { - const result = '0'; - component.value = 0; + it('getChangeStyle: should return `po-color-03`', () => { + component.status = undefined; + component.color = 'color-03'; + + const getChangeStyle = component.getChangeStyle(); + + expect(getChangeStyle).toEqual('po-color-03'); + }); - fixture.detectChanges(); + it('setLiterals: should set notificationLabel when value > 1', () => { + const labelFake = 'Home'; + const valueFake = 2; + component.value = valueFake; + component.areaLabel = labelFake; + component.literals = { notifications: 'notifications', notification: 'notification' }; - const badgeValue = fixture.nativeElement.querySelector(badgeValueSelector); + component.setLiterals(); - expect(badgeValue.innerHTML).toBe(result); + expect(component.notificationLabel).toBe(`${labelFake} ${valueFake} notifications`); }); - it('should create `po-badge` with value `99+` if `value` is greater than 99', () => { - const result = '99+'; - component.value = 101; + it('setLiterals: should set notificationLabel when value < 1', () => { + const labelFake = 'Home'; + const valueFake = 1; + component.value = valueFake; + component.areaLabel = labelFake; + component.literals = { notifications: 'notifications', notification: 'notification' }; + + component.setLiterals(); - fixture.detectChanges(); + expect(component.notificationLabel).toBe(`${labelFake} ${valueFake} notification`); + }); - const badgeValue = fixture.nativeElement.querySelector(badgeValueSelector); + it('setLiterals: should set notificationLabel when value > 1 and areaLabel is empty', () => { + const valueFake = 2; + component.value = valueFake; + component.literals = { notifications: 'notifications', notification: 'notification' }; - expect(badgeValue.innerHTML).toBe(result); + component.setLiterals(); + + expect(component.notificationLabel).toBe(` ${valueFake} notifications`); }); - it('should create `po-badge` with value `99` if `value` is `99`', () => { - const result = '99'; - component.value = 99; + it('setLiterals: should set notificationLabel when value < 1 and areaLabel is empty', () => { + const valueFake = 1; + component.value = valueFake; + component.literals = { notifications: 'notifications', notification: 'notification' }; - fixture.detectChanges(); + component.setLiterals(); - const badgeValue = fixture.nativeElement.querySelector(badgeValueSelector); + expect(component.notificationLabel).toBe(` ${valueFake} notification`); + }); - expect(badgeValue.innerHTML).toBe(result); + it('setStatus: should called', () => { + component.badgeValue = null; + + component.setStatus(); + + expect(component.isNotification).toBeFalsy(); + expect(component.badgeValue).toEqual(null); }); - it('should create `po-badge` with `po-color-07` if `color` is `undefined`', () => { - component.value = 10; - component.color = undefined; + it('switchIconStatus: should apply all icon positive if status is posivite', () => { + component.status = 'positive'; + component.icon = true; + + component.switchIconStatus(); + + expect(component.badgeIcon).toBe('po-icon-ok'); + }); - fixture.detectChanges(); + it('switchIconStatus: should apply all icon negative if status is negative', () => { + component.status = 'negative'; + component.icon = true; - const badge = fixture.nativeElement.querySelector(badgeColorDefaultSelector); + component.switchIconStatus(); - expect(badge).toBeTruthy(); + expect(component.badgeIcon).toBe('po-icon-minus'); }); - it('should create `po-badge` with `po-color-07` if `color` is `invalid`', () => { - component.value = 10; - component.color = 'color-33'; + it('switchIconStatus: should apply all icon warning if status is warning', () => { + component.status = 'warning'; + component.icon = true; - fixture.detectChanges(); + component.switchIconStatus(); - const badge = fixture.nativeElement.querySelector(badgeColorDefaultSelector); + expect(component.badgeIcon).toBe('po-icon-warning'); + }); + + it('switchIconStatus: should apply all icon disabled if status is disabled', () => { + component.status = 'disabled'; + component.icon = true; - expect(badge).toBeTruthy(); + component.switchIconStatus(); + + expect(component.badgeIcon).toBe(''); }); - it('should create `po-badge` with `po-color-03` if `color` is `color-03`', () => { - component.value = 10; - component.color = 'color-03'; + it('setBadgeNotification: should return true and set isNotification true when not status', () => { + const setBadgeNotification = component['setBadgeNotification'](2); - fixture.detectChanges(); + expect(component.isNotification).toBeTrue(); + expect(setBadgeNotification).toBeTrue(); + }); + + it('setBadgeNotification: should return true and set isNotification true when status', () => { + component.status = 'positive'; + component.badgeValue = null; + + const setBadgeNotification = component['setBadgeNotification'](1); + + expect(component.isNotification).toBeFalse(); + expect(component.badgeValue).toBe(null); + expect(setBadgeNotification).toBeFalse(); + }); + + it('setBadgeValue: should call checkBadgeValue', () => { + spyOn(component, 'checkBadgeValue'); + component.value = 2; + + component['setBadgeValue'](); + + expect(component['checkBadgeValue']).toHaveBeenCalledWith(component.value); + }); + + it('checkBadgeValue: should called with value is valid', () => { + component['checkBadgeValue'](2); + + expect(component.isValidValue).toBeTrue(); + expect(component.badgeValue).toBe('2'); + }); + + it('checkBadgeValue: should called with value is invalid', () => { + component['checkBadgeValue'](-10); + + expect(component.isValidValue).toBeFalse(); + expect(component.badgeValue).toBe(''); + }); + + it('formatBadgeValue: should called formatBadgeValue and return 9+', () => { + const formatBadgeValue = component['formatBadgeValue'](11); + + expect(formatBadgeValue).toBe('9+'); + }); - const badge = fixture.nativeElement.querySelector('.po-badge.po-color-03'); + it('formatBadgeValue: should called formatBadgeValue with 2 and return 2', () => { + const formatBadgeValue = component['formatBadgeValue'](2); - expect(badge).toBeTruthy(); + expect(formatBadgeValue).toBe('2'); }); }); }); diff --git a/projects/ui/src/lib/components/po-badge/po-badge.component.ts b/projects/ui/src/lib/components/po-badge/po-badge.component.ts index 50f1fe79e..0984cc861 100644 --- a/projects/ui/src/lib/components/po-badge/po-badge.component.ts +++ b/projects/ui/src/lib/components/po-badge/po-badge.component.ts @@ -1,14 +1,144 @@ -import { Component } from '@angular/core'; +import { Component, OnChanges, OnInit, SimpleChanges, inject } from '@angular/core'; import { PoBadgeBaseComponent } from './po-badge-base.component'; +import { PoBadgeLiterals } from './interfaces/po-badge-literals.interface'; +import { PoBadgeLiteralsDefault } from './interfaces/po-badge-literals-default'; +import { PoLanguageService } from '../../services/po-language/po-language.service'; + +const PO_BADGE_MAX_NOTIFICATIONS = 9; /** * @docsExtends PoBadgeBaseComponent * - * @docsPrivate + * @example + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * */ @Component({ selector: 'po-badge', - templateUrl: './po-badge.component.html' + templateUrl: './po-badge.component.html', + styles: [':host { display: inline-block; vertical-align: middle; }'] }) -export class PoBadgeComponent extends PoBadgeBaseComponent {} +export class PoBadgeComponent extends PoBadgeBaseComponent implements OnInit, OnChanges { + isNotification: boolean = false; + notificationLabel: string = ''; + literals: PoBadgeLiterals; + badgeIcon: string = ''; + isValidValue: boolean = false; + + private poLanguageService = inject(PoLanguageService); + + ngOnInit(): void { + this.literals = PoBadgeLiteralsDefault[this.poLanguageService.getShortLanguage()]; + + this.initialize(); + } + + ngOnChanges(changes: SimpleChanges): void { + if (changes['status'] || changes['icon']) { + this.setStatus(); + } + + if (changes['value']) { + this.setBadgeValue(); + this.setBadgeNotification(changes['value'].currentValue); + this.setLiterals(); + } + } + + initialize() { + this.setStatus(); + this.setLiterals(); + this.setBadgeValue(); + this.setBadgeNotification(this.value); + } + + getChangeStyle() { + if ((this.color === 'color-07' && !this.customColor) || this.status) { + return 'po-badge-default'; + } else if (this.color) { + return `po-${this.color}`; + } + } + + setLiterals() { + if (this.value) { + this.notificationLabel = + this.value > 1 + ? `${this.areaLabel ?? ''} ${this.value} ${this.literals?.notifications}` + : `${this.areaLabel ?? ''} ${this.value} ${this.literals?.notification}`; + } else { + this.notificationLabel = `${this.areaLabel ?? ''} ${this.literals?.notification}`; + } + } + + setStatus() { + this.isNotification = false; + this.badgeValue = null; + this.switchIconStatus(); + } + + switchIconStatus() { + if (typeof this.icon === 'boolean') { + this.badgeIcon = ''; + + if (['positive', 'negative', 'warning', 'disabled'].includes(this.status)) { + switch (this.status) { + case 'positive': + this.badgeIcon = 'po-icon-ok'; + break; + + case 'negative': + this.badgeIcon = 'po-icon-minus'; + break; + + case 'warning': + this.badgeIcon = 'po-icon-warning'; + break; + } + } + } else { + this.badgeIcon = this.icon as string; + } + } + + private setBadgeNotification(value: number): boolean { + if (value > 1 && !this.status) { + this.isNotification = true; + return true; + } else { + this.isNotification = false; + this.badgeValue = null; + return false; + } + } + + private setBadgeValue(): void { + if (this.value) { + this.checkBadgeValue(this.value); + } + } + + private checkBadgeValue(value: number): void { + this.isValidValue = Number.isInteger(value) && value >= 1; + this.badgeValue = this.isValidValue ? this.formatBadgeValue(value) : ''; + } + + private formatBadgeValue(value: number): string { + return value > PO_BADGE_MAX_NOTIFICATIONS ? '9+' : value.toString(); + } +} diff --git a/projects/ui/src/lib/components/po-badge/po-badge.module.ts b/projects/ui/src/lib/components/po-badge/po-badge.module.ts index 85be67447..c1bfaf73a 100644 --- a/projects/ui/src/lib/components/po-badge/po-badge.module.ts +++ b/projects/ui/src/lib/components/po-badge/po-badge.module.ts @@ -2,6 +2,7 @@ import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; import { PoBadgeComponent } from './po-badge.component'; +import { PoIconModule } from '../po-icon'; /** * @description @@ -9,7 +10,7 @@ import { PoBadgeComponent } from './po-badge.component'; * Módulo do componente po-badge. */ @NgModule({ - imports: [CommonModule], + imports: [CommonModule, PoIconModule], declarations: [PoBadgeComponent], exports: [PoBadgeComponent] }) diff --git a/projects/ui/src/lib/components/po-badge/samples/sample-po-badge-basic/sample-po-badge-basic.component.html b/projects/ui/src/lib/components/po-badge/samples/sample-po-badge-basic/sample-po-badge-basic.component.html new file mode 100644 index 000000000..7b4d0fba1 --- /dev/null +++ b/projects/ui/src/lib/components/po-badge/samples/sample-po-badge-basic/sample-po-badge-basic.component.html @@ -0,0 +1 @@ + diff --git a/projects/ui/src/lib/components/po-badge/samples/sample-po-badge-basic/sample-po-badge-basic.component.ts b/projects/ui/src/lib/components/po-badge/samples/sample-po-badge-basic/sample-po-badge-basic.component.ts new file mode 100644 index 000000000..c8ff9622d --- /dev/null +++ b/projects/ui/src/lib/components/po-badge/samples/sample-po-badge-basic/sample-po-badge-basic.component.ts @@ -0,0 +1,7 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'sample-po-badge-basic', + templateUrl: './sample-po-badge-basic.component.html' +}) +export class SamplePoBadgeBasicComponent {} diff --git a/projects/ui/src/lib/components/po-badge/samples/sample-po-badge-labs/sample-po-badge-labs.component.html b/projects/ui/src/lib/components/po-badge/samples/sample-po-badge-labs/sample-po-badge-labs.component.html new file mode 100644 index 000000000..bec070142 --- /dev/null +++ b/projects/ui/src/lib/components/po-badge/samples/sample-po-badge-labs/sample-po-badge-labs.component.html @@ -0,0 +1,64 @@ +
+ +
+ +
+ +
+
+ + +
+ +
+ + + + + + + + + + + +
+ +
+ +
+
diff --git a/projects/ui/src/lib/components/po-badge/samples/sample-po-badge-labs/sample-po-badge-labs.component.ts b/projects/ui/src/lib/components/po-badge/samples/sample-po-badge-labs/sample-po-badge-labs.component.ts new file mode 100644 index 000000000..d0f0d0b36 --- /dev/null +++ b/projects/ui/src/lib/components/po-badge/samples/sample-po-badge-labs/sample-po-badge-labs.component.ts @@ -0,0 +1,69 @@ +import { Component, OnInit } from '@angular/core'; +import { PoCheckboxGroupOption, PoRadioGroupOption } from '@po-ui/ng-components'; + +@Component({ + selector: 'sample-po-badge-labs', + templateUrl: './sample-po-badge-labs.component.html' +}) +export class SamplePoBadgeLabsComponent implements OnInit { + value: number; + icon: string; + size: string; + status: any; + properties: Array; + color: string; + showIcon: boolean; + + propertiesOptions: Array = [{ value: 'showBorder', label: 'Show Border' }]; + + iconsOptions: Array = [ + { label: 'ph-check', value: 'ph ph-check' }, + { label: 'ph-check-circle', value: 'ph ph-check-circle' }, + { label: 'po-icon-ok', value: 'po-icon-ok' }, + { label: 'fa-minus', value: 'fa fa-minus' }, + { label: 'None', value: 'true', disabled: true } + ]; + + sizesOptions: Array = [ + { label: 'Small', value: 'small' }, + { label: 'Medium', value: 'medium' }, + { label: 'Large', value: 'large' } + ]; + + statusOptions: Array = [ + { label: 'Positive', value: 'positive' }, + { label: 'Negative', value: 'negative' }, + { label: 'Warning', value: 'warning' }, + { label: 'Disabled', value: 'disabled' }, + { label: 'None', value: undefined } + ]; + + constructor() {} + + ngOnInit() { + this.restore(); + } + + propertiesChange(event) { + this.properties = event; + } + + statusChange(event) { + this.iconsOptions[4].disabled = false; + } + + iconsChange(event) { + this.showIcon = event === 'true' ? true : false; + } + + restore() { + this.size = 'medium'; + this.status = undefined; + this.icon = undefined; + this.color = undefined; + this.value = undefined; + this.showIcon = false; + this.iconsOptions[4].disabled = true; + this.properties = []; + } +} diff --git a/projects/ui/src/lib/components/po-badge/samples/sample-po-badge-message/sample-po-badge-message.component.css b/projects/ui/src/lib/components/po-badge/samples/sample-po-badge-message/sample-po-badge-message.component.css new file mode 100644 index 000000000..7e0265f92 --- /dev/null +++ b/projects/ui/src/lib/components/po-badge/samples/sample-po-badge-message/sample-po-badge-message.component.css @@ -0,0 +1,41 @@ +.card-container { + display: flex; + flex-direction: column; + gap: 0.5em; +} + +.card { + display: flex; + align-items: center; + justify-content: center; + gap: 0.5rem; + position: relative; +} + +.card .card-name-user { + font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif; +} + +.po-badge-wrap { + position: absolute; + top: -0.2em; + right: 2; +} + +svg { + width: 1.5rem; + height: 1.5rem; + flex: none; + stroke-width: 2; + stroke-linecap: round; +} + +svg[kind='online'] { + stroke: #0ea5e9; + fill: #e0f2fe; +} + +svg[kind='offline'] { + fill: white; + stroke: #dc2626; +} diff --git a/projects/ui/src/lib/components/po-badge/samples/sample-po-badge-message/sample-po-badge-message.component.html b/projects/ui/src/lib/components/po-badge/samples/sample-po-badge-message/sample-po-badge-message.component.html new file mode 100644 index 000000000..a2f31bb98 --- /dev/null +++ b/projects/ui/src/lib/components/po-badge/samples/sample-po-badge-message/sample-po-badge-message.component.html @@ -0,0 +1,19 @@ +
+
+
+ + + + +

+ {{ user.nome }} + +

+
+
+
diff --git a/projects/ui/src/lib/components/po-badge/samples/sample-po-badge-message/sample-po-badge-message.component.ts b/projects/ui/src/lib/components/po-badge/samples/sample-po-badge-message/sample-po-badge-message.component.ts new file mode 100644 index 000000000..74e28d0c2 --- /dev/null +++ b/projects/ui/src/lib/components/po-badge/samples/sample-po-badge-message/sample-po-badge-message.component.ts @@ -0,0 +1,23 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'sample-po-badge-message', + templateUrl: './sample-po-badge-message.component.html', + styleUrls: ['./sample-po-badge-message.component.css'] +}) +export class SamplePoBadgeMessageComponent { + users: Array = [ + { + nome: 'Leonardo da vinci', + status: 'online' + }, + { + nome: 'Johann Pachelbel', + status: 'offline' + }, + { + nome: 'Amadeus Mozart', + status: 'offline' + } + ]; +}