Skip to content

Commit

Permalink
fix(avatar): fix HostBinding classes for onPush Host
Browse files Browse the repository at this point in the history
The classes of the Hostbinding where not set correctly for onPush Hosts.
Classes where not merged correctly.
Now the classes of the icon are set and detected by the host correctly.
fixed unit tests as they would have never failed cause of setTimeout.

close #36
  • Loading branch information
elite-benni committed Nov 16, 2023
1 parent e66b4d5 commit 09336eb
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,15 @@ import { ClassValue } from 'clsx';
exportAs: 'avatarFallback',
})
export class BrnAvatarFallbackDirective {
private readonly element = inject(ElementRef).nativeElement;
readonly userCls = signal<ClassValue>('');
readonly useAutoColor = signal(false);
readonly textContent = inject(ElementRef).nativeElement.textContent;

getTextContent(): string {
return this.element.textContent;
}

@Input() set class(cls: ClassValue | string) {
this.userCls.set(cls);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { Component, PLATFORM_ID } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed, fakeAsync } from '@angular/core/testing';
import { HlmAvatarFallbackDirective } from './hlm-avatar-fallback.directive';
import { hexColorFor, isBright } from '@spartan-ng/ui-avatar-brain';

@Component({
selector: 'hlm-mock',
standalone: true,
imports: [HlmAvatarFallbackDirective],
template: `<span hlmAvatarFallback [class]="userCls" [autoColor]="false">fallback2</span>`,
template: `<span hlmAvatarFallback [class]="userCls" [autoColor]="autoColor">fallback2</span>`,
})
class HlmMockComponent {
userCls = '';
Expand Down Expand Up @@ -36,12 +36,9 @@ describe('HlmAvatarFallbackDirective', () => {

it('should add any user defined classes', async () => {
component.userCls = 'test-class';
fixture.detectChanges();

// fallback uses Promise.resolve().then() so we need to wait for the next tick
setTimeout(() => {
expect(fixture.nativeElement.querySelector('img').className).toContain('test-class');
});
fixture.detectChanges();
expect(fixture.nativeElement.querySelector('span').className).toContain('test-class');
});

describe('autoColor', () => {
Expand All @@ -50,19 +47,16 @@ describe('HlmAvatarFallbackDirective', () => {
fixture.detectChanges();
});

it('should remove the bg-muted class from the component', () => {
setTimeout(() => {
expect(fixture.nativeElement.querySelector('span').className).not.toContain('bg-muted');
});
});
it('should remove the bg-muted class from the component', fakeAsync(() => {
fixture.detectChanges();
expect(fixture.nativeElement.querySelector('span').className).not.toContain('bg-muted');
}));

it('should remove add a text color class and hex backgroundColor style depending on its content', () => {
const hex = hexColorFor('fallback2');
const textCls = isBright(hex) ? 'text-black' : 'text-white';
setTimeout(() => {
expect(fixture.nativeElement.querySelector('span').className).toContain(textCls);
expect(fixture.nativeElement.querySelector('span').style.backgroundColor).toBe(hex);
});
expect(fixture.nativeElement.querySelector('span').className).toContain(textCls);
expect(fixture.nativeElement.querySelector('span').style.backgroundColor).toBe('rgb(144, 53, 149)');
});
});
});
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { computed, Directive, effect, HostBinding, inject } from '@angular/core';
import { computed, Directive, inject } from '@angular/core';
import { BrnAvatarFallbackDirective, hexColorFor, isBright } from '@spartan-ng/ui-avatar-brain';
import { hlm } from '@spartan-ng/ui-core';
import { ClassValue } from 'clsx';
Expand All @@ -22,34 +22,19 @@ const generateAutoColorTextCls = (hex?: string) => {
inputs: ['class:class', 'autoColor:autoColor'],
},
],
host: {
'[class]': 'generatedClasses()',
'[style.backgroundColor]': "hex() || ''",
},
})
export class HlmAvatarFallbackDirective {
private readonly brn = inject(BrnAvatarFallbackDirective);
private readonly hex = computed(() => {
if (!this.brn.useAutoColor() || !this.brn.textContent) return;
return hexColorFor(this.brn.textContent);
if (!this.brn.useAutoColor() || !this.brn.getTextContent()) return;
return hexColorFor(this.brn.getTextContent());
});

private readonly autoColorTextCls = computed(() => generateAutoColorTextCls(this.hex()));

@HostBinding('class')
protected cls = generateClasses(this.brn?.userCls(), this.autoColorTextCls());

@HostBinding('style.backgroundColor')
protected backgroundColor = this.hex() || '';

constructor() {
effect(() => {
const cls = generateClasses(this.brn.userCls(), this.autoColorTextCls());
Promise.resolve().then(() => {
this.cls = cls;
});
});
effect(() => {
const hex = this.hex() || '';
Promise.resolve().then(() => {
this.backgroundColor = hex;
});
});
}
protected readonly generatedClasses = computed(() => generateClasses(this.brn?.userCls(), this.autoColorTextCls()));
}

0 comments on commit 09336eb

Please sign in to comment.