diff --git a/ngx-fudis/projects/ngx-fudis/src/lib/components/language-badge-group/language-badge-group.component.scss b/ngx-fudis/projects/ngx-fudis/src/lib/components/language-badge-group/language-badge-group.component.scss index 3a5d0fa48..13f786055 100644 --- a/ngx-fudis/projects/ngx-fudis/src/lib/components/language-badge-group/language-badge-group.component.scss +++ b/ngx-fudis/projects/ngx-fudis/src/lib/components/language-badge-group/language-badge-group.component.scss @@ -2,5 +2,7 @@ .fudis-language-badge-group { display: inline-flex; + align-items: center; margin-left: spacing.$spacing-xxs; + height: spacing.$spacing-md; } diff --git a/ngx-fudis/projects/ngx-fudis/src/lib/components/language-badge-group/language-badge-group.component.spec.ts b/ngx-fudis/projects/ngx-fudis/src/lib/components/language-badge-group/language-badge-group.component.spec.ts index 0c53adc4a..b7b140a56 100644 --- a/ngx-fudis/projects/ngx-fudis/src/lib/components/language-badge-group/language-badge-group.component.spec.ts +++ b/ngx-fudis/projects/ngx-fudis/src/lib/components/language-badge-group/language-badge-group.component.spec.ts @@ -1,10 +1,12 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { MockComponent } from 'ng-mocks'; import { By } from '@angular/platform-browser'; import { FudisLanguageBadgeContent } from '../../types/miscellaneous'; import { TooltipApiDirective } from '../../directives/tooltip/tooltip-api.directive'; import { LanguageBadgeGroupComponent } from './language-badge-group.component'; import { LanguageBadgeComponent } from './language-badge/language-badge.component'; +import { getElement } from '../../utilities/tests/utilities'; +import { MatTooltipModule } from '@angular/material/tooltip'; +import { TooltipDirective } from '../../directives/tooltip/tooltip.directive'; const providedLanguages: FudisLanguageBadgeContent = { en: 'en', fi: 'fi' }; @@ -18,9 +20,11 @@ describe('LanguageBadgeGroupComponent', () => { await TestBed.configureTestingModule({ declarations: [ LanguageBadgeGroupComponent, - MockComponent(LanguageBadgeComponent), + LanguageBadgeComponent, TooltipApiDirective, + TooltipDirective, ], + imports: [MatTooltipModule], }).compileComponents(); }); @@ -54,7 +58,21 @@ describe('LanguageBadgeGroupComponent', () => { expect(missingLanguage).toContain('sv'); }); + }); + + describe('Interaction', () => { + it('should update language and emit output when clicked', () => { + jest.spyOn(component.handleBadgeClick, 'emit'); + + const fiButton = getElement(fixture, '.fudis-language-badge') as HTMLButtonElement; + + fiButton.click(); - // TODO: add test for output emit + expect(component.handleBadgeClick.emit).toHaveBeenCalledWith('fi'); + + fixture.detectChanges(); + + expect(component.selectedLanguage).toEqual('fi'); + }); }); }); diff --git a/ngx-fudis/projects/ngx-fudis/src/lib/components/language-badge-group/language-badge-group.component.ts b/ngx-fudis/projects/ngx-fudis/src/lib/components/language-badge-group/language-badge-group.component.ts index 45fa373c0..8c7d7d405 100644 --- a/ngx-fudis/projects/ngx-fudis/src/lib/components/language-badge-group/language-badge-group.component.ts +++ b/ngx-fudis/projects/ngx-fudis/src/lib/components/language-badge-group/language-badge-group.component.ts @@ -69,9 +69,10 @@ export class LanguageBadgeGroupComponent extends TooltipApiDirective implements } /** - * Emits clicked badge lang output on click + * Set selected language and emits clicked language */ protected _updateLanguage(value: FudisLanguageAbbr) { + this.selectedLanguage = value; this.handleBadgeClick.emit(value); } diff --git a/ngx-fudis/projects/ngx-fudis/src/lib/components/language-badge-group/language-badge/language-badge.component.html b/ngx-fudis/projects/ngx-fudis/src/lib/components/language-badge-group/language-badge/language-badge.component.html index 7f4f77f59..7e7e2a18d 100644 --- a/ngx-fudis/projects/ngx-fudis/src/lib/components/language-badge-group/language-badge/language-badge.component.html +++ b/ngx-fudis/projects/ngx-fudis/src/lib/components/language-badge-group/language-badge/language-badge.component.html @@ -1,13 +1,16 @@ diff --git a/ngx-fudis/projects/ngx-fudis/src/lib/components/language-badge-group/language-badge/language-badge.component.scss b/ngx-fudis/projects/ngx-fudis/src/lib/components/language-badge-group/language-badge/language-badge.component.scss index ec0ca979c..554d0745e 100644 --- a/ngx-fudis/projects/ngx-fudis/src/lib/components/language-badge-group/language-badge/language-badge.component.scss +++ b/ngx-fudis/projects/ngx-fudis/src/lib/components/language-badge-group/language-badge/language-badge.component.scss @@ -1,13 +1,14 @@ @use "../../../foundations/colors/mixins.scss" as colors; @use "../../../foundations/typography/mixins.scss" as typography; @use "../../../foundations/focus/mixins.scss" as focus; -@use "../../../foundations/colors/mixins.scss" as colorMixin; @use "../../../foundations/borders/mixins.scss" as border; @use "../../../foundations/utilities/mixins.scss" as utilities; @use "../../../foundations/spacing/tokens.scss" as spacing; -.fudis-language-badge-host { +.fudis-language-badge { @include colors.bg-color("transparent"); + @include border.border-none; + @include utilities.box-reset; display: inline-flex; align-items: center; @@ -18,23 +19,21 @@ &:focus-within { @include focus.focus-generic; } -} - -.fudis-language-badge { - @include typography.body-text-sm-regular; - @include colorMixin.bg-color("white"); - @include border.border("1px", "solid", "gray-dark"); - @include utilities.box-reset; - - border-radius: 50%; - width: spacing.$spacing-md; - height: spacing.$spacing-md; - text-align: center; - /* stylelint-disable-next-line unit-disallowed-list */ - letter-spacing: 0.02rem; - &:focus-visible { - @include border.outline-none; + &__content { + @include typography.body-text-sm-regular; + @include colors.bg-color("white"); + @include border.border("1px", "solid", "gray-dark"); + + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + min-width: spacing.$spacing-md; + min-height: spacing.$spacing-md; + text-align: center; + /* stylelint-disable-next-line unit-disallowed-list */ + letter-spacing: calc(0.02rem / var(--fudis-rem-multiplier)); } &__missing { diff --git a/ngx-fudis/projects/ngx-fudis/src/lib/components/language-badge-group/language-badge/language-badge.component.spec.ts b/ngx-fudis/projects/ngx-fudis/src/lib/components/language-badge-group/language-badge/language-badge.component.spec.ts index 684535f22..2920d46f5 100644 --- a/ngx-fudis/projects/ngx-fudis/src/lib/components/language-badge-group/language-badge/language-badge.component.spec.ts +++ b/ngx-fudis/projects/ngx-fudis/src/lib/components/language-badge-group/language-badge/language-badge.component.spec.ts @@ -3,6 +3,7 @@ import { MatTooltipModule } from '@angular/material/tooltip'; import { By } from '@angular/platform-browser'; import { LanguageBadgeComponent } from './language-badge.component'; import { TooltipDirective } from '../../../directives/tooltip/tooltip.directive'; +import { getElement } from '../../../utilities/tests/utilities'; describe('LanguageBadgeComponent', () => { let component: LanguageBadgeComponent; @@ -20,16 +21,13 @@ describe('LanguageBadgeComponent', () => { component = fixture.componentInstance; component.language = 'en'; component.variant = 'standard'; + component.label = 'This is test label'; + component.ngOnChanges({ + label: { firstChange: true, currentValue: 'This is test label', previousValue: '' }, + }); fixture.detectChanges(); }); - function assertLanguageBadgeHasClasses(classes: string): void { - const childSpan = fixture.nativeElement.childNodes; - const componentClasses = childSpan[0].className.split(' ').sort(); - - expect(componentClasses).toEqual(classes.split(' ').sort()); - } - it('should create', () => { expect(component).toBeTruthy(); }); @@ -37,33 +35,42 @@ describe('LanguageBadgeComponent', () => { describe('Contents', () => { it('should always have class name missing if language badge variant is a type missing', () => { component.variant = 'missing'; + component.ngOnChanges({ + variant: { firstChange: false, currentValue: 'missing', previousValue: 'standard' }, + }); fixture.detectChanges(); - assertLanguageBadgeHasClasses('fudis-language-badge fudis-language-badge__missing'); + + const classes = getElement(fixture, '.fudis-language-badge__content').className; + + expect(classes).toEqual('fudis-language-badge__content fudis-language-badge__missing'); }); it('should always have class name selected if language badge is selected', () => { component.selected = true; + component.ngOnChanges({ + selected: { firstChange: false, currentValue: true, previousValue: false }, + }); fixture.detectChanges(); - assertLanguageBadgeHasClasses( - 'fudis-language-badge fudis-language-badge__standard fudis-language-badge--selected', + + const classes = getElement(fixture, '.fudis-language-badge__content').className; + + expect(classes).toEqual( + 'fudis-language-badge__content fudis-language-badge__standard fudis-language-badge--selected', ); }); it('should have given label matching to aria-label', () => { - component.label = 'This is test label'; - component.ngOnChanges(); fixture.detectChanges(); - const LanguageBadgeLabel = fixture.debugElement.query(By.css('.fudis-language-badge')); + const label = fixture.debugElement.query(By.css('.fudis-language-badge')); - expect(LanguageBadgeLabel.nativeElement.getAttribute('aria-label')).toEqual( - 'This is test label', - ); + expect(label.nativeElement.getAttribute('aria-label')).toEqual('This is test label'); }); it('should have given label and selected text matching to aria-label', () => { - component.label = 'This is test label'; component.selected = true; - component.ngOnChanges(); + component.ngOnChanges({ + selected: { firstChange: false, currentValue: true, previousValue: false }, + }); fixture.detectChanges(); const LanguageBadgeLabel = fixture.debugElement.query(By.css('.fudis-language-badge')); @@ -73,9 +80,10 @@ describe('LanguageBadgeComponent', () => { }); it('should have given label and missing text matching to aria-label', () => { - component.label = 'This is test label'; component.variant = 'missing'; - component.ngOnChanges(); + component.ngOnChanges({ + variant: { firstChange: false, currentValue: 'missing', previousValue: 'standard' }, + }); fixture.detectChanges(); const LanguageBadgeLabel = fixture.debugElement.query(By.css('.fudis-language-badge')); @@ -83,7 +91,17 @@ describe('LanguageBadgeComponent', () => { 'This is test label (Missing translation)', ); }); + }); + + describe('Interaction', () => { + it('should emit output when clicked', () => { + jest.spyOn(component.handleClick, 'emit'); - // TODO: Add test for output event + const button = getElement(fixture, '.fudis-language-badge') as HTMLButtonElement; + + button.click(); + + expect(component.handleClick.emit).toHaveBeenCalledWith(component.language); + }); }); }); diff --git a/ngx-fudis/projects/ngx-fudis/src/lib/components/language-badge-group/language-badge/language-badge.component.ts b/ngx-fudis/projects/ngx-fudis/src/lib/components/language-badge-group/language-badge/language-badge.component.ts index daf32baab..f98fb004f 100644 --- a/ngx-fudis/projects/ngx-fudis/src/lib/components/language-badge-group/language-badge/language-badge.component.ts +++ b/ngx-fudis/projects/ngx-fudis/src/lib/components/language-badge-group/language-badge/language-badge.component.ts @@ -1,15 +1,9 @@ +import { Component, EventEmitter, Input, OnChanges, Output, Signal, effect } from '@angular/core'; import { - Component, - EventEmitter, - HostBinding, - Input, - OnChanges, - OnInit, - Output, - Signal, - ViewEncapsulation, -} from '@angular/core'; -import { FudisLanguageAbbr, FudisTranslationConfig } from '../../../types/miscellaneous'; + FudisComponentChanges, + FudisLanguageAbbr, + FudisTranslationConfig, +} from '../../../types/miscellaneous'; import { TooltipApiDirective } from '../../../directives/tooltip/tooltip-api.directive'; import { FudisTranslationService } from '../../../services/translation/translation.service'; @@ -17,20 +11,17 @@ import { FudisTranslationService } from '../../../services/translation/translati selector: 'fudis-language-badge', styleUrls: ['./language-badge.component.scss'], templateUrl: './language-badge.component.html', - encapsulation: ViewEncapsulation.None, }) -export class LanguageBadgeComponent extends TooltipApiDirective implements OnInit, OnChanges { +export class LanguageBadgeComponent extends TooltipApiDirective implements OnChanges { constructor(private _translationService: FudisTranslationService) { super(); - this._translations = this._translationService.getTranslations(); - this._selectedLabel = this._translations().LANGUAGE_BADGE.ARIA_LABEL.SELECTED; - this._missingTranslation = this._translations().LANGUAGE_BADGE.ARIA_LABEL.MISSING_TRANSLATION; - } - /** - * Binding host CSS class to component wrapper - */ - @HostBinding('class') private _classes = 'fudis-language-badge-host'; + effect(() => { + this._translations = this._translationService.getTranslations(); + this._selectedLabel = this._translations().LANGUAGE_BADGE.ARIA_LABEL.SELECTED; + this._missingTranslation = this._translations().LANGUAGE_BADGE.ARIA_LABEL.MISSING_TRANSLATION; + }); + } /* * Language abbreviation for Language Badge @@ -82,12 +73,10 @@ export class LanguageBadgeComponent extends TooltipApiDirective implements OnIni */ protected _translations: Signal; - ngOnInit(): void { - this._setLabel(); - } - - ngOnChanges(): void { - this._setLabel(); + ngOnChanges(changes: FudisComponentChanges): void { + if (changes.selected || changes.variant || changes.label) { + this._setLabel(); + } } /**