From e216cf5446ce40b5bd43bac2747c8d73b058904f Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Thu, 13 Dec 2018 18:10:01 +0200 Subject: [PATCH 1/4] refactor(avatar): allow for more robust styling of the avatar --- .../src/lib/avatar/avatar.component.html | 16 +- .../src/lib/avatar/avatar.component.spec.ts | 203 ++++++++++++------ .../src/lib/avatar/avatar.component.ts | 86 ++++++-- .../components/avatar/_avatar-component.scss | 35 ++- .../components/avatar/_avatar-theme.scss | 15 +- src/app/avatar/avatar.sample.html | 4 +- 6 files changed, 240 insertions(+), 119 deletions(-) diff --git a/projects/igniteui-angular/src/lib/avatar/avatar.component.html b/projects/igniteui-angular/src/lib/avatar/avatar.component.html index b0d47c90bb2..55f188f6fc7 100644 --- a/projects/igniteui-angular/src/lib/avatar/avatar.component.html +++ b/projects/igniteui-angular/src/lib/avatar/avatar.component.html @@ -1,19 +1,17 @@ + + + + -
+
-
- {{initials.substring(0, 2)}} -
+ {{initials.substring(0, 2)}}
- - {{icon}} - + {{icon}} - diff --git a/projects/igniteui-angular/src/lib/avatar/avatar.component.spec.ts b/projects/igniteui-angular/src/lib/avatar/avatar.component.spec.ts index cee2df5eb55..6c739c2cd81 100644 --- a/projects/igniteui-angular/src/lib/avatar/avatar.component.spec.ts +++ b/projects/igniteui-angular/src/lib/avatar/avatar.component.spec.ts @@ -5,12 +5,25 @@ import { } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { IgxIconModule } from '../icon/index'; -import { IgxAvatarComponent, IgxAvatarModule } from './avatar.component'; +import { IgxAvatarComponent, AvatarType, Size } from './avatar.component'; import { configureTestSuite } from '../test-utils/configure-suite'; -describe('Avatar', () => { +fdescribe('Avatar', () => { configureTestSuite(); + const baseClass = 'igx-avatar'; + + const classes = { + default: `${baseClass}--default`, + round: `${baseClass}--rounded`, + small: `${baseClass}--small`, + medium: `${baseClass}--medium`, + large: `${baseClass}--large`, + image: `${baseClass}--image`, + initials: `${baseClass}--initials`, + icon: `${baseClass}--icon` + }; + beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [ @@ -18,8 +31,7 @@ describe('Avatar', () => { AvatarWithAttribsComponent, IgxAvatarComponent, InitIconAvatarComponent, - InitImageAvatarComponent, - InitAvatarWithAriaComponent + InitImageAvatarComponent ], imports: [IgxIconModule] }) @@ -29,122 +41,183 @@ describe('Avatar', () => { it('Initializes avatar with auto-incremented id', () => { const fixture = TestBed.createComponent(InitAvatarComponent); fixture.detectChanges(); - const avatar = fixture.componentInstance.avatar; - const domAvatar = fixture.debugElement.query(By.css('igx-avatar')).nativeElement; + const instance = fixture.componentInstance.avatar; + const hostEl = fixture.debugElement.query(By.css(baseClass)).nativeElement; + + expect(instance.id).toContain('igx-avatar-'); + expect(hostEl.id).toContain('igx-avatar-'); + + instance.id = 'customAvatar'; + fixture.detectChanges(); + + expect(instance.id).toBe('customAvatar'); + expect(hostEl.id).toBe('customAvatar'); + }); + + it('Initializes square and round avatar', () => { + const fixture = TestBed.createComponent(AvatarWithAttribsComponent); + fixture.detectChanges(); + const instance = fixture.componentInstance.avatar; + const hostEl = fixture.debugElement.query(By.css(baseClass)).nativeElement; + + expect(instance.roundShape).toBeTruthy(); + expect(hostEl.classList).toContain(classes.round); - expect(avatar.id).toContain('igx-avatar-'); - expect(domAvatar.id).toContain('igx-avatar-'); + instance.roundShape = false; + + fixture.detectChanges(); + expect(instance.roundShape).toBeFalsy(); + expect(hostEl.classList).not.toContain(classes.round); + }); + + it('Initializes small, medium, and large avatar', () => { + const fixture = TestBed.createComponent(AvatarWithAttribsComponent); + fixture.detectChanges(); + const instance = fixture.componentInstance.avatar; + const hostEl = fixture.debugElement.query(By.css(baseClass)).nativeElement; + + expect(instance.size).toEqual(Size.SMALL); + expect(hostEl.classList).toContain(classes.small); + + instance.size = Size.MEDIUM; + fixture.detectChanges(); + expect(instance.size).toEqual(Size.MEDIUM); + expect(hostEl.classList).not.toContain(classes.medium); - avatar.id = 'customAvatar'; + instance.size = Size.LARGE; fixture.detectChanges(); + expect(instance.size).toEqual(Size.LARGE); + expect(hostEl.classList).not.toContain(classes.large); - expect(avatar.id).toBe('customAvatar'); - expect(domAvatar.id).toBe('customAvatar'); + instance.size = 'nonsense'; + fixture.detectChanges(); + expect(instance.size).toEqual(Size.SMALL); + expect(hostEl.classList).toContain(classes.small); }); - it('Initializes avatar with initials', () => { + it('Initializes default avatar', () => { const fixture = TestBed.createComponent(InitAvatarComponent); fixture.detectChanges(); - const avatar = fixture.componentInstance.avatar; - expect(fixture.debugElement.query(By.css('.igx-avatar__initials'))).toBeTruthy(); - expect(avatar.roundShape).toEqual(false); + const instance = fixture.componentInstance.avatar; + const hostEl = fixture.debugElement.query(By.css(baseClass)).nativeElement; + + expect(instance.type).toEqual(AvatarType.DEFAULT); + expect(instance.initials).toBeUndefined(); + expect(instance.src).toBeUndefined(); + expect(instance.icon).toBeUndefined(); + + expect(hostEl.textContent).toEqual('TEST'); + expect(hostEl.classList).toContain(classes.default); }); - it('Initializes round avatar with initials', () => { + + it('Initializes initials avatar', () => { const fixture = TestBed.createComponent(AvatarWithAttribsComponent); fixture.detectChanges(); - const avatar = fixture.componentInstance.avatar; - expect(avatar.elementRef.nativeElement.classList.contains('igx-avatar--rounded')).toBeTruthy(); - expect(fixture.debugElement.query(By.css('.igx-avatar__initials'))).toBeTruthy(); - expect(avatar.roundShape).toBeTruthy(); + const instance = fixture.componentInstance.avatar; + const hostEl = fixture.debugElement.query(By.css(baseClass)).nativeElement; + + expect(instance.type).toEqual(AvatarType.INITIALS); + expect(instance.initials).toEqual('ZK'); + expect(hostEl.querySelector('span').textContent).toEqual('ZK'); + expect(hostEl.classList).toContain(classes.initials); }); it('Initializes icon avatar', () => { const fixture = TestBed.createComponent(InitIconAvatarComponent); fixture.detectChanges(); - const avatar = fixture.componentInstance.avatar; - const spanEl = avatar.elementRef.nativeElement.querySelector('.igx-avatar__icon'); - - expect(avatar.image === undefined).toBeTruthy(); - expect(avatar.src).toBeFalsy(); - expect(spanEl).toBeTruthy(); - expect(avatar.elementRef.nativeElement.classList.contains('igx-avatar--small')).toBeTruthy(); - expect(spanEl.classList.length === 1).toBeTruthy(); - expect(avatar.roundShape).toBeFalsy(); - - // For ARIA - expect(spanEl.getAttribute('aria-roledescription') === 'icon type avatar').toBeTruthy(); + const instance = fixture.componentInstance.avatar; + const hostEl = fixture.debugElement.query(By.css(baseClass)).nativeElement; + + expect(instance.type).toEqual(AvatarType.ICON); + expect(instance.icon).toBeTruthy(); + expect(hostEl.classList).toContain(classes.icon); }); it('Initializes image avatar', () => { const fixture = TestBed.createComponent(InitImageAvatarComponent); fixture.detectChanges(); - const avatar = fixture.componentInstance.avatar; + const instance = fixture.componentInstance.avatar; + const hostEl = fixture.debugElement.query(By.css(baseClass)).nativeElement; - expect(avatar.image).toBeTruthy(); - expect(avatar.image.nativeElement.style.backgroundImage.length !== 0).toBeTruthy(); - expect(avatar.elementRef.nativeElement.classList.contains('igx-avatar--large')).toBeTruthy(); - expect(avatar.image.nativeElement.classList.length === 1).toBeTruthy(); - expect(avatar.roundShape).toBeTruthy(); + expect(instance.type).toEqual(AvatarType.IMAGE); + expect(instance.image).toBeTruthy(); + expect(instance.image.nativeElement.style.backgroundImage).toBeDefined(); - // For ARIA - expect(avatar.image.nativeElement.getAttribute('aria-roledescription') === 'image type avatar').toBeTruthy(); - expect(avatar.roleDescription === 'image type avatar').toBeTruthy(); + expect(instance.image.nativeElement.classList).toContain(`${baseClass}__image`); + expect(hostEl.classList).toContain(classes.image); }); - it('Should set ARIA attributes.', () => { - const fixture = TestBed.createComponent(InitAvatarWithAriaComponent); + it('Sets background and foreground colors', () => { + const fixture = TestBed.createComponent(AvatarWithAttribsComponent); fixture.detectChanges(); - const avatar = fixture.componentInstance.avatar; + const instance = fixture.componentInstance.avatar; + const hostEl = fixture.debugElement.query(By.css(baseClass)).nativeElement; + + expect(hostEl.style.background).toEqual(instance.bgColor); + expect(hostEl.style.color).toEqual(instance.color); - expect(avatar.elementRef.nativeElement.querySelector('.igx-avatar__initials') - .getAttribute('aria-roledescription')).toMatch('initials type avatar'); + instance.bgColor = '#000'; + instance.color = '#fff'; + + fixture.detectChanges(); + expect(hostEl.style.background).toEqual('rgb(0, 0, 0)'); + expect(hostEl.style.color).toEqual('rgb(255, 255, 255)'); + }); + + it('Sets ARIA attributes', () => { + const fixture = TestBed.createComponent(InitImageAvatarComponent); + fixture.detectChanges(); + const instance = fixture.componentInstance.avatar; + const hostEl = fixture.debugElement.query(By.css(baseClass)).nativeElement; + + expect(instance.roleDescription).toEqual('image avatar'); + expect(hostEl.getAttribute('role')).toEqual('img'); + expect(hostEl.getAttribute('aria-roledescription')).toEqual('image avatar'); + expect(hostEl.getAttribute('aria-label')).toEqual('avatar'); }); }); @Component({ - template: ` - `}) + template: `TEST` +}) class InitAvatarComponent { @ViewChild(IgxAvatarComponent) public avatar: IgxAvatarComponent; } @Component({ - template: ``}) + template: ` + ` +}) class AvatarWithAttribsComponent { @ViewChild(IgxAvatarComponent) public avatar: IgxAvatarComponent; public initials = 'ZK'; - public bgColor = 'lightblue'; + public color = 'orange'; + public bgColor = 'royalblue'; public roundShape = 'true'; } @Component({ - template: ` - `}) + template: `` +}) class InitIconAvatarComponent { @ViewChild(IgxAvatarComponent) public avatar: IgxAvatarComponent; } @Component({ - template: ` - `}) + template: `` +}) class InitImageAvatarComponent { @ViewChild(IgxAvatarComponent) public avatar: IgxAvatarComponent; // tslint:disable-next-line:max-line-length public source = 'data:image/jpeg;base64,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'; } - -@Component({ - template: ` - `}) -class InitAvatarWithAriaComponent { - @ViewChild(IgxAvatarComponent) public avatar: IgxAvatarComponent; -} diff --git a/projects/igniteui-angular/src/lib/avatar/avatar.component.ts b/projects/igniteui-angular/src/lib/avatar/avatar.component.ts index c706ee638ae..4ee0d2ddcae 100644 --- a/projects/igniteui-angular/src/lib/avatar/avatar.component.ts +++ b/projects/igniteui-angular/src/lib/avatar/avatar.component.ts @@ -19,6 +19,14 @@ export enum Size { MEDIUM = 'medium', LARGE = 'large' } + +export enum AvatarType { + DEFAULT = 'default', + INITIALS = 'initials', + IMAGE = 'image', + ICON = 'icon' +} + /** * **Ignite UI for Angular Avatar** - * [Documentation](https://www.infragistics.com/products/ignite-ui-angular/angular/components/avatar.html) @@ -38,7 +46,6 @@ export enum Size { }) export class IgxAvatarComponent implements OnInit, AfterViewInit { - /** * This is a reference to the avatar `image` element in the DOM. * @@ -50,6 +57,11 @@ export class IgxAvatarComponent implements OnInit, AfterViewInit { @ViewChild('image') public image: ElementRef; + /** + *@hidden + */ + @ViewChild('defaultTemplate', { read: TemplateRef }) + protected defaultTemplate: TemplateRef; /** *@hidden @@ -62,11 +74,13 @@ export class IgxAvatarComponent implements OnInit, AfterViewInit { */ @ViewChild('initialsTemplate', { read: TemplateRef }) protected initialsTemplate: TemplateRef; + /** *@hidden */ @ViewChild('iconTemplate', { read: TemplateRef }) protected iconTemplate: TemplateRef; + /** * Returns the `aria-label` of the avatar. * @@ -77,6 +91,7 @@ export class IgxAvatarComponent implements OnInit, AfterViewInit { */ @HostBinding('attr.aria-label') public ariaLabel = 'avatar'; + /** * Returns the `role` attribute of the avatar. * @@ -88,6 +103,7 @@ export class IgxAvatarComponent implements OnInit, AfterViewInit { */ @HostBinding('attr.role') public role = 'img'; + /** * Returns the class of the avatar. * @@ -99,6 +115,7 @@ export class IgxAvatarComponent implements OnInit, AfterViewInit { */ @HostBinding('class.igx-avatar') public cssClass = 'igx-avatar'; + /** * Returns the type of the avatar. * The avatar can be: `"initials type avatar"`, `"icon type avatar"` or `"image type avatar"`. @@ -109,6 +126,8 @@ export class IgxAvatarComponent implements OnInit, AfterViewInit { * * @memberof IgxAvatarComponent */ + + @HostBinding('attr.aria-roledescription') public roleDescription: string; /** @@ -128,6 +147,7 @@ export class IgxAvatarComponent implements OnInit, AfterViewInit { @HostBinding('attr.id') @Input() public id = `igx-avatar-${NEXT_ID++}`; + /** * Sets a round shape to the avatar if `roundShape` is `"true"`. * By default the shape of the avatar is a square. @@ -138,6 +158,7 @@ export class IgxAvatarComponent implements OnInit, AfterViewInit { * * @memberof IgxAvatarComponent */ + @HostBinding('class.igx-avatar--rounded') @Input() public roundShape = false; @@ -151,6 +172,8 @@ export class IgxAvatarComponent implements OnInit, AfterViewInit { * * @memberof IgxAvatarComponent */ + + @HostBinding('style.color') @Input() public color: string; @@ -163,6 +186,8 @@ export class IgxAvatarComponent implements OnInit, AfterViewInit { * * @memberof IgxAvatarComponent */ + + @HostBinding('style.background') @Input() public bgColor: string; @@ -237,26 +262,52 @@ export class IgxAvatarComponent implements OnInit, AfterViewInit { this._size = 'small'; } } + /** - * Returns the template of the avatar. + * Returns the type of the avatar. * * ```typescript - * let template = this.avatar.template; + * let avatarType = this.avatar.type; * ``` * * @memberof IgxAvatarComponent */ - get template() { + get type(): AvatarType { if (this.src) { - return this.imageTemplate; + return AvatarType.IMAGE; + } + + if (this.icon) { + return AvatarType.ICON; } if (this.initials) { - return this.initialsTemplate; + return AvatarType.INITIALS; } - return this.iconTemplate; + return AvatarType.DEFAULT; + } + /** + * Returns the template of the avatar. + * + * ```typescript + * let template = this.avatar.template; + * ``` + * + * @memberof IgxAvatarComponent + */ + get template(): TemplateRef { + switch (this.type) { + case AvatarType.IMAGE: + return this.imageTemplate; + case AvatarType.INITIALS: + return this.initialsTemplate; + case AvatarType.ICON: + return this.iconTemplate; + default: + return this.defaultTemplate; + } } constructor(public elementRef: ElementRef) { } @@ -272,18 +323,23 @@ export class IgxAvatarComponent implements OnInit, AfterViewInit { *@hidden */ public ngAfterViewInit() { - this.elementRef.nativeElement.classList.add(`igx-avatar--${this._size}`); + this.elementRef.nativeElement.classList + .add(`igx-avatar--${this._size}`, `igx-avatar--${this.type}`); } + /** * @hidden */ - private getRole() { - if (this.initials) { - return 'initials type avatar'; - } else if (this.src) { - return 'image type avatar'; - } else { - return 'icon type avatar'; + private getRole(): string { + switch (this.type) { + case AvatarType.IMAGE: + return 'image avatar'; + case AvatarType.ICON: + return 'icon avatar'; + case AvatarType.INITIALS: + return 'initials avatar'; + default: + return 'custom avatar'; } } diff --git a/projects/igniteui-angular/src/lib/core/styles/components/avatar/_avatar-component.scss b/projects/igniteui-angular/src/lib/core/styles/components/avatar/_avatar-component.scss index 68611e1251b..de393efc9fb 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/avatar/_avatar-component.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/avatar/_avatar-component.scss @@ -12,6 +12,11 @@ @extend %igx-avatar-display !optional; + @include e(image) { + @extend %igx-avatar-inner !optional; + @extend %igx-avatar-image !optional; + } + @include m(rounded) { @extend %igx-avatar-display !optional; @extend %igx-avatar--rounded !optional; @@ -19,40 +24,30 @@ @include m(small) { @extend %igx-avatar--small !optional; - - @include e(initials) { - @extend %igx-avatar-initials--small !optional; - } } @include m(medium) { @extend %igx-avatar--medium !optional; - - @include e(initials) { - @extend %igx-avatar-initials--medium !optional; - } } @include m(large) { @extend %igx-avatar--large !optional; - - @include e(initials) { - @extend %igx-avatar-initials--large !optional; - } } - @include e(icon) { - @extend %igx-avatar-inner !optional; + @include m(icon) { @extend %igx-avatar-icon !optional; } - @include e(image) { - @extend %igx-avatar-inner !optional; - @extend %igx-avatar-image !optional; + @include m(initials) { + @extend %igx-avatar-initials !optional; + @extend %igx-avatar-initials--small !optional; } - @include e(initials) { - @extend %igx-avatar-inner !optional; - @extend %igx-avatar-initials !optional; + @include mx(medium, initials) { + @extend %igx-avatar-initials--medium !optional; + } + + @include mx(large, initials) { + @extend %igx-avatar-initials--large !optional; } } diff --git a/projects/igniteui-angular/src/lib/core/styles/components/avatar/_avatar-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/avatar/_avatar-theme.scss index a83bd05a921..e0c780b1a87 100644 --- a/projects/igniteui-angular/src/lib/core/styles/components/avatar/_avatar-theme.scss +++ b/projects/igniteui-angular/src/lib/core/styles/components/avatar/_avatar-theme.scss @@ -67,8 +67,13 @@ $large-size: 88px; %igx-avatar-display { + display: inline-flex; + justify-content: center; + align-items: center; position: relative; user-select: none; + color: --var($theme, 'initials-color'); + background: --var($theme, 'initials-background'); } %igx-avatar--rounded { @@ -94,15 +99,12 @@ } %igx-avatar-inner { - width: inherit; - height: inherit; + width: 100%; + height: 100%; border-radius: inherit; } %igx-avatar-icon { - display: flex; - justify-content: center; - align-items: center; color: --var($theme, 'icon-color'); background: --var($theme, 'icon-background'); } @@ -115,9 +117,6 @@ } %igx-avatar-initials { - display: flex; - justify-content: center; - align-items: center; text-transform: uppercase; color: --var($theme, 'initials-color'); background-color: --var($theme, 'initials-background'); diff --git a/src/app/avatar/avatar.sample.html b/src/app/avatar/avatar.sample.html index 37c13eba090..df5c74820f2 100644 --- a/src/app/avatar/avatar.sample.html +++ b/src/app/avatar/avatar.sample.html @@ -10,7 +10,7 @@

Circular Avatars

- +
@@ -34,7 +34,7 @@

Circular Avatars

- +
From c847341338dd397b4007e33147b6119fb601bf0e Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Thu, 13 Dec 2018 22:34:27 +0200 Subject: [PATCH 2/4] Update avatar.component.spec.ts --- .../igniteui-angular/src/lib/avatar/avatar.component.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/igniteui-angular/src/lib/avatar/avatar.component.spec.ts b/projects/igniteui-angular/src/lib/avatar/avatar.component.spec.ts index 6c739c2cd81..b76b968d928 100644 --- a/projects/igniteui-angular/src/lib/avatar/avatar.component.spec.ts +++ b/projects/igniteui-angular/src/lib/avatar/avatar.component.spec.ts @@ -9,7 +9,7 @@ import { IgxAvatarComponent, AvatarType, Size } from './avatar.component'; import { configureTestSuite } from '../test-utils/configure-suite'; -fdescribe('Avatar', () => { +describe('Avatar', () => { configureTestSuite(); const baseClass = 'igx-avatar'; From 3fd69b9deb22d20c848f8b1b7ceffba416ce1a44 Mon Sep 17 00:00:00 2001 From: Simeon Simeonoff Date: Mon, 17 Dec 2018 12:13:35 +0200 Subject: [PATCH 3/4] Update avatar.component.spec.ts --- .../igniteui-angular/src/lib/avatar/avatar.component.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/igniteui-angular/src/lib/avatar/avatar.component.spec.ts b/projects/igniteui-angular/src/lib/avatar/avatar.component.spec.ts index b76b968d928..e97f91c67fa 100644 --- a/projects/igniteui-angular/src/lib/avatar/avatar.component.spec.ts +++ b/projects/igniteui-angular/src/lib/avatar/avatar.component.spec.ts @@ -70,7 +70,7 @@ describe('Avatar', () => { expect(hostEl.classList).not.toContain(classes.round); }); - it('Initializes small, medium, and large avatar', () => { + it('Can change its size', () => { const fixture = TestBed.createComponent(AvatarWithAttribsComponent); fixture.detectChanges(); const instance = fixture.componentInstance.avatar; From 28bca4f06af7a7279805496ff667f4a84a59aa2b Mon Sep 17 00:00:00 2001 From: SAndreeva Date: Tue, 18 Dec 2018 17:26:55 +0200 Subject: [PATCH 4/4] chore(*): fix tests using avatar #3444 --- .../src/lib/test-utils/template-strings.spec.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/projects/igniteui-angular/src/lib/test-utils/template-strings.spec.ts b/projects/igniteui-angular/src/lib/test-utils/template-strings.spec.ts index b64ff56aca3..82b1bf321b8 100644 --- a/projects/igniteui-angular/src/lib/test-utils/template-strings.spec.ts +++ b/projects/igniteui-angular/src/lib/test-utils/template-strings.spec.ts @@ -142,7 +142,9 @@ export class ColumnDefinitions { - +
+ +