diff --git a/projects/ion/package.json b/projects/ion/package.json index 29e405538..3692f4650 100644 --- a/projects/ion/package.json +++ b/projects/ion/package.json @@ -1,6 +1,6 @@ { "name": "@brisanet/ion", - "version": "0.0.66", + "version": "0.0.67", "repository": { "type": "git", "url": "git+https://github.com/Brisanet/ion.git" diff --git a/projects/ion/src/lib/alert/alert.component.html b/projects/ion/src/lib/alert/alert.component.html index 5d696e67a..43889575a 100644 --- a/projects/ion/src/lib/alert/alert.component.html +++ b/projects/ion/src/lib/alert/alert.component.html @@ -9,7 +9,14 @@ class="alert-icon" [type]="iconType" > - {{ message }} + {{ + message + }} + + + + + +> => { + return await render(AlertCustomBodyComponent, { + imports: [CommonModule, IonAlertModule], + declarations: [AlertCustomBodyComponent], + }); +}; + describe('AlertComponent', () => { it('Should render alert', async () => { expect(await sut()).toHaveClass(alertDefaultClass); }); - it('Should have an alert message', async () => { - expect(await sut()).toHaveTextContent(defaultValue.message); - }); - it('Should render with success icon by default', async () => { await sut(); expect(await screen.findByTestId(alertIDs.iconStatus)).toBeInTheDocument(); }); - it('Should show the informed message', async () => { - const label = 'Testing message in Alert'; - const element = await sut({ message: label }); - expect(element).toHaveTextContent(label); - }); - it.each(alertTypes)('Should render %s type', async (type: StatusType) => { const element = await sut({ ...defaultValue, type }); expect(element).toHaveClass(type); @@ -96,4 +102,30 @@ describe('AlertComponent', () => { const element = await sut({ ...defaultValue, hideBackground: true }); expect(element).toHaveClass('without-background'); }); + + describe('With a string provided', () => { + it('Should have an alert message', async () => { + expect(await sut()).toHaveTextContent(defaultValue.message as string); + }); + + it('Should show the informed message', async () => { + const label = 'Testing message in Alert'; + const element = await sut({ message: label }); + expect(element).toHaveTextContent(label); + }); + }); + + describe('With a custom body provided', () => { + beforeEach(async () => { + await sutAlertWithCustomBody(); + }); + + it('should render with the custom body provided', async () => { + expect(screen.getByTestId('ion-alert-custom-body')).toBeVisible(); + }); + + it('should not render the plain message', async () => { + expect(screen.queryByTestId('ion-alert-message')).toBeNull(); + }); + }); }); diff --git a/projects/ion/src/lib/alert/alert.component.ts b/projects/ion/src/lib/alert/alert.component.ts index ee0d3a76e..b69712c09 100644 --- a/projects/ion/src/lib/alert/alert.component.ts +++ b/projects/ion/src/lib/alert/alert.component.ts @@ -4,6 +4,8 @@ import { Input, OnChanges, OnInit, + SimpleChanges, + TemplateRef, ViewChild, } from '@angular/core'; import { StatusType } from '../core/types'; @@ -22,7 +24,7 @@ const iconTypes = { styleUrls: ['./alert.component.scss'], }) export class IonAlertComponent implements OnInit, OnChanges { - @Input() message!: string; + @Input() message!: string | TemplateRef; @Input() type?: StatusType = 'success'; @Input() closable? = false; @Input() hideBackground? = false; @@ -31,6 +33,8 @@ export class IonAlertComponent implements OnInit, OnChanges { iconType: IconType; + hasPlainText: boolean; + closeEvent(): void { this.ionAlert.nativeElement.remove(); } @@ -45,7 +49,10 @@ export class IonAlertComponent implements OnInit, OnChanges { } } - ngOnChanges(): void { + ngOnChanges(changes: SimpleChanges): void { this.setIcon(); + if (changes.message) { + this.hasPlainText = typeof this.message === 'string'; + } } } diff --git a/projects/ion/src/lib/alert/mocks/alert-custom-body.component.ts b/projects/ion/src/lib/alert/mocks/alert-custom-body.component.ts new file mode 100644 index 000000000..ff8f7d661 --- /dev/null +++ b/projects/ion/src/lib/alert/mocks/alert-custom-body.component.ts @@ -0,0 +1,19 @@ +import { Component } from '@angular/core'; + +@Component({ + template: ` + + + + + + Custom + Alert + message + + + + + `, +}) +export class AlertCustomBodyComponent {} diff --git a/projects/ion/src/lib/click-outside.directive.ts b/projects/ion/src/lib/click-outside.directive.ts index 6d7dbbbd8..c00c4faed 100644 --- a/projects/ion/src/lib/click-outside.directive.ts +++ b/projects/ion/src/lib/click-outside.directive.ts @@ -1,9 +1,9 @@ import { Directive, ElementRef, - Output, EventEmitter, HostListener, + Output, } from '@angular/core'; @Directive({ diff --git a/projects/ion/src/lib/core/types/alert.ts b/projects/ion/src/lib/core/types/alert.ts index de10c07ab..070ce5eaf 100644 --- a/projects/ion/src/lib/core/types/alert.ts +++ b/projects/ion/src/lib/core/types/alert.ts @@ -1,7 +1,8 @@ +import { TemplateRef } from '@angular/core'; import { StatusType } from './status'; export interface IonAlertProps { - message: string; + message: string | TemplateRef; type?: StatusType; closable?: boolean; hideBackground?: boolean; diff --git a/projects/ion/src/lib/modal/modal.service.ts b/projects/ion/src/lib/modal/modal.service.ts index c4994b301..5d2bbe73e 100644 --- a/projects/ion/src/lib/modal/modal.service.ts +++ b/projects/ion/src/lib/modal/modal.service.ts @@ -1,4 +1,3 @@ -import { SafeAny } from './../utils/safe-any'; import { DOCUMENT } from '@angular/common'; import { ApplicationRef, @@ -10,6 +9,7 @@ import { Type, } from '@angular/core'; import { Observable, Subject } from 'rxjs'; +import { SafeAny } from './../utils/safe-any'; import { IonModalComponent } from './component/modal.component'; import { @@ -72,8 +72,10 @@ export class IonModalService { } closeModal(): void { - this.appRef.detachView(this.modalComponentRef.hostView); - this.componentSubscriber.complete(); - this.modalComponentRef.destroy(); + if (this.modalComponentRef) { + this.appRef.detachView(this.modalComponentRef.hostView); + this.componentSubscriber.complete(); + this.modalComponentRef.destroy(); + } } } diff --git a/stories/Alert.stories.mdx b/stories/Alert.stories.mdx index c3b770127..380cbf333 100644 --- a/stories/Alert.stories.mdx +++ b/stories/Alert.stories.mdx @@ -12,16 +12,17 @@ export const Template = (args) => ; No Ion o alerta pode receber 5 parâmetros, sendo eles: -- `message`. Indicando a mensagem que será mostrada no alerta. +- `message`. Indicando o conteúdo que será mostrada no alerta, podendo ser uma string ou um TemplateRef. - `type`. Indicando o tipo do alerta. - `closable`. Indicando se o alerta pode ou não ser fechado. - `width`. Indicando a largura do alerta. - `height`. Indicando a altura do alerta. Dentre os parâmetros o `message` é o unico obrigatório, os outros possuem valores padrões. -O alerta pode ser chamado da seguinte forma: +O alerta pode ser chamado das seguintes formas: - `` +- ` Custom Alert Message ` ## Message diff --git a/stories/AlertCustomBody.stories.mdx b/stories/AlertCustomBody.stories.mdx new file mode 100644 index 000000000..575818a5b --- /dev/null +++ b/stories/AlertCustomBody.stories.mdx @@ -0,0 +1,27 @@ +import { Canvas, Meta, Story } from '@storybook/addon-docs'; +import { moduleMetadata } from '@storybook/angular'; +import { IonAlertComponent } from '../projects/ion/src/lib/alert/alert.component.ts'; +import { IonAlertModule } from '../projects/ion/src/lib/alert/alert.module.ts'; +import { IonSharedModule } from '../projects/ion/src/public-api'; +import { CommonModule } from '@angular/common'; +import { AlertCustomBodyComponent } from '../projects/ion/src/lib/alert/mocks/alert-custom-body.component.ts'; + + + +export const Template = () => ; + +### Custom Message + + + + {Template.bind({})} + +
+ Custom + Alert + message +