From 8838422e1e1fab91d0756dfeee0fbe22a1de5bb3 Mon Sep 17 00:00:00 2001 From: RasmusKjeldgaard Date: Thu, 21 Nov 2024 11:25:59 +0100 Subject: [PATCH 01/19] Add translation service and initial translations --- .../calendar/src/calendar.component.html | 5 +-- .../calendar/src/calendar.component.ts | 4 ++- libs/designsystem/shared/src/public_api.ts | 2 ++ .../src/translation/translation.interface.ts | 9 ++++++ .../src/translation/translation.service.ts | 32 +++++++++++++++++++ .../shared/src/translation/translations/da.ts | 11 +++++++ .../src/translation/translations/en-gb.ts | 12 +++++++ .../src/translation/translations/en-us.ts | 11 +++++++ 8 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 libs/designsystem/shared/src/translation/translation.interface.ts create mode 100644 libs/designsystem/shared/src/translation/translation.service.ts create mode 100644 libs/designsystem/shared/src/translation/translations/da.ts create mode 100644 libs/designsystem/shared/src/translation/translations/en-gb.ts create mode 100644 libs/designsystem/shared/src/translation/translations/en-us.ts diff --git a/libs/designsystem/calendar/src/calendar.component.html b/libs/designsystem/calendar/src/calendar.component.html index 5c88496710..ee463fd66e 100644 --- a/libs/designsystem/calendar/src/calendar.component.html +++ b/libs/designsystem/calendar/src/calendar.component.html @@ -4,7 +4,7 @@ kirby-button type="button" class="no-margin" - aria-label="Previous month" + [attr.aria-label]="translationService.currentTranslation.previousMonth" [attr.aria-disabled]="_canNavigateBack ? null : true" [noDecoration]="true" (click)="_changeMonth(-1)" @@ -21,7 +21,7 @@ kirby-button type="button" class="no-margin" - aria-label="Next month" + [attr.aria-label]="translationService.currentTranslation.nextMonth" [attr.aria-disabled]="_canNavigateForward ? null : true" [noDecoration]="true" (click)="_changeMonth(1)" @@ -34,6 +34,7 @@ [usePopover]="usePopover" [selectedIndex]="navigatedYear" [items]="navigableYears" + [attr.aria-label]="translationService.currentTranslation.selectYear" popout="left" (change)="_changeYear($event)" > diff --git a/libs/designsystem/calendar/src/calendar.component.ts b/libs/designsystem/calendar/src/calendar.component.ts index 59e13125af..669467751f 100644 --- a/libs/designsystem/calendar/src/calendar.component.ts +++ b/libs/designsystem/calendar/src/calendar.component.ts @@ -40,6 +40,7 @@ import { DropdownModule } from '@kirbydesign/designsystem/dropdown'; import { UniqueIdGenerator } from '@kirbydesign/designsystem/helpers'; import { IconModule } from '@kirbydesign/designsystem/icon'; +import { TranslationService } from '@kirbydesign/designsystem/shared'; import { CalendarDay, CalendarDayMetadata } from './interfaces/calendar-day'; import { CalendarYearNavigatorConfig } from './interfaces/calendar-year-navigator-config'; @@ -223,7 +224,8 @@ export class CalendarComponent implements OnInit, OnChanges { constructor( @Inject(LOCALE_ID) locale: string, private elementRef: ElementRef, - private cdr: ChangeDetectorRef + private cdr: ChangeDetectorRef, + public translationService: TranslationService ) { this.locale = this.mapLocale(locale); this.timeZoneName = Intl.DateTimeFormat().resolvedOptions().timeZone; diff --git a/libs/designsystem/shared/src/public_api.ts b/libs/designsystem/shared/src/public_api.ts index ff43d995c5..aa17b5d63d 100644 --- a/libs/designsystem/shared/src/public_api.ts +++ b/libs/designsystem/shared/src/public_api.ts @@ -9,3 +9,5 @@ export * from './dynamic-component'; export * from './fit-heading/index'; export * from './controls/label-helpers'; + +export * from './translation/translation.service'; diff --git a/libs/designsystem/shared/src/translation/translation.interface.ts b/libs/designsystem/shared/src/translation/translation.interface.ts new file mode 100644 index 0000000000..77d671b16e --- /dev/null +++ b/libs/designsystem/shared/src/translation/translation.interface.ts @@ -0,0 +1,9 @@ +export interface Translation { + back: string; + close: string; + nextMonth: string; + nextSlide: string; + previousMonth: string; + previousSlide: string; + selectYear: string; +} diff --git a/libs/designsystem/shared/src/translation/translation.service.ts b/libs/designsystem/shared/src/translation/translation.service.ts new file mode 100644 index 0000000000..dccccda146 --- /dev/null +++ b/libs/designsystem/shared/src/translation/translation.service.ts @@ -0,0 +1,32 @@ +import { Injectable } from '@angular/core'; +import { Inject, LOCALE_ID } from '@angular/core'; +import { da } from './translations/da'; +import { enUS } from './translations/en-us'; +import { Translation } from './translation.interface'; + +@Injectable({ + providedIn: 'root', +}) +export class TranslationService { + private translations: { [key: string]: Translation } = { + da, + 'en-US': enUS, + }; + + public currentTranslation: Translation = enUS; + + constructor(@Inject(LOCALE_ID) private localeId: string) { + this.setCurrentTranslation(localeId); + } + + setCurrentTranslation(localeId: string): string { + const translation = this.translations[localeId]; + + if (!translation) { + console.warn(`Translation not found for locale "${this.localeId}", falling back to "en-US"`); + return; + } + + this.currentTranslation = translation; + } +} diff --git a/libs/designsystem/shared/src/translation/translations/da.ts b/libs/designsystem/shared/src/translation/translations/da.ts new file mode 100644 index 0000000000..720f565431 --- /dev/null +++ b/libs/designsystem/shared/src/translation/translations/da.ts @@ -0,0 +1,11 @@ +import { Translation } from '../translation.interface'; + +export const da: Translation = { + back: 'Tilbage', + close: 'Luk', + nextMonth: 'Næste måned', + nextSlide: 'Næste slide', + previousMonth: 'Forrige måned', + previousSlide: 'Forrige slide', + selectYear: 'Vælg år', +}; diff --git a/libs/designsystem/shared/src/translation/translations/en-gb.ts b/libs/designsystem/shared/src/translation/translations/en-gb.ts new file mode 100644 index 0000000000..bb1bb77e82 --- /dev/null +++ b/libs/designsystem/shared/src/translation/translations/en-gb.ts @@ -0,0 +1,12 @@ +// TODO: Duplicate translation to anticipate differences between en-gb and en-us, or point to the same? +import { Translation } from '../translation.interface'; + +export const enGB: Translation = { + back: 'Back', + close: 'Close', + nextMonth: 'Next month', + nextSlide: 'Next slide', + previousMonth: 'Previous month', + previousSlide: 'Previous slide', + selectYear: 'Select year', +}; diff --git a/libs/designsystem/shared/src/translation/translations/en-us.ts b/libs/designsystem/shared/src/translation/translations/en-us.ts new file mode 100644 index 0000000000..be863e7f68 --- /dev/null +++ b/libs/designsystem/shared/src/translation/translations/en-us.ts @@ -0,0 +1,11 @@ +import { Translation } from '../translation.interface'; + +export const enUS: Translation = { + back: 'Back', + close: 'Close', + nextMonth: 'Next month', + nextSlide: 'Next slide', + previousMonth: 'Previous month', + previousSlide: 'Previous slide', + selectYear: 'Select year', +}; From 71a0512e987d5d69e3076cb7ef164ded48269504 Mon Sep 17 00:00:00 2001 From: RasmusKjeldgaard Date: Thu, 21 Nov 2024 15:00:51 +0100 Subject: [PATCH 02/19] Simplify english locale translations into one --- .../shared/src/translation/translation.service.ts | 11 ++++++----- .../shared/src/translation/translations/en-gb.ts | 12 ------------ .../src/translation/translations/{en-us.ts => en.ts} | 2 +- 3 files changed, 7 insertions(+), 18 deletions(-) delete mode 100644 libs/designsystem/shared/src/translation/translations/en-gb.ts rename libs/designsystem/shared/src/translation/translations/{en-us.ts => en.ts} (87%) diff --git a/libs/designsystem/shared/src/translation/translation.service.ts b/libs/designsystem/shared/src/translation/translation.service.ts index dccccda146..d39ff8ec39 100644 --- a/libs/designsystem/shared/src/translation/translation.service.ts +++ b/libs/designsystem/shared/src/translation/translation.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { Inject, LOCALE_ID } from '@angular/core'; import { da } from './translations/da'; -import { enUS } from './translations/en-us'; +import { en } from './translations/en'; import { Translation } from './translation.interface'; @Injectable({ @@ -10,20 +10,21 @@ import { Translation } from './translation.interface'; export class TranslationService { private translations: { [key: string]: Translation } = { da, - 'en-US': enUS, + en, }; - public currentTranslation: Translation = enUS; + public currentTranslation: Translation = en; constructor(@Inject(LOCALE_ID) private localeId: string) { this.setCurrentTranslation(localeId); } setCurrentTranslation(localeId: string): string { - const translation = this.translations[localeId]; + const baseLocaleId = localeId.split('-')[0]; + const translation = this.translations[baseLocaleId]; if (!translation) { - console.warn(`Translation not found for locale "${this.localeId}", falling back to "en-US"`); + console.warn(`Translation not found for locale "${this.localeId}", falling back to "en"`); return; } diff --git a/libs/designsystem/shared/src/translation/translations/en-gb.ts b/libs/designsystem/shared/src/translation/translations/en-gb.ts deleted file mode 100644 index bb1bb77e82..0000000000 --- a/libs/designsystem/shared/src/translation/translations/en-gb.ts +++ /dev/null @@ -1,12 +0,0 @@ -// TODO: Duplicate translation to anticipate differences between en-gb and en-us, or point to the same? -import { Translation } from '../translation.interface'; - -export const enGB: Translation = { - back: 'Back', - close: 'Close', - nextMonth: 'Next month', - nextSlide: 'Next slide', - previousMonth: 'Previous month', - previousSlide: 'Previous slide', - selectYear: 'Select year', -}; diff --git a/libs/designsystem/shared/src/translation/translations/en-us.ts b/libs/designsystem/shared/src/translation/translations/en.ts similarity index 87% rename from libs/designsystem/shared/src/translation/translations/en-us.ts rename to libs/designsystem/shared/src/translation/translations/en.ts index be863e7f68..e36ef5b0ca 100644 --- a/libs/designsystem/shared/src/translation/translations/en-us.ts +++ b/libs/designsystem/shared/src/translation/translations/en.ts @@ -1,6 +1,6 @@ import { Translation } from '../translation.interface'; -export const enUS: Translation = { +export const en: Translation = { back: 'Back', close: 'Close', nextMonth: 'Next month', From 18154fb17a80d2da53dd1c6712f437ae388ea3c5 Mon Sep 17 00:00:00 2001 From: RasmusKjeldgaard Date: Fri, 22 Nov 2024 11:17:44 +0100 Subject: [PATCH 03/19] Readability improvements --- .../calendar/src/calendar.component.html | 6 +++--- .../shared/src/translation/translation.interface.ts | 1 + .../shared/src/translation/translation.service.ts | 12 +++++++----- .../shared/src/translation/translations/da.ts | 1 + .../shared/src/translation/translations/en.ts | 1 + 5 files changed, 13 insertions(+), 8 deletions(-) diff --git a/libs/designsystem/calendar/src/calendar.component.html b/libs/designsystem/calendar/src/calendar.component.html index ee463fd66e..ab03bcbfac 100644 --- a/libs/designsystem/calendar/src/calendar.component.html +++ b/libs/designsystem/calendar/src/calendar.component.html @@ -4,7 +4,7 @@ kirby-button type="button" class="no-margin" - [attr.aria-label]="translationService.currentTranslation.previousMonth" + [attr.aria-label]="translationService.activeTranslation.previousMonth" [attr.aria-disabled]="_canNavigateBack ? null : true" [noDecoration]="true" (click)="_changeMonth(-1)" @@ -21,7 +21,7 @@ kirby-button type="button" class="no-margin" - [attr.aria-label]="translationService.currentTranslation.nextMonth" + [attr.aria-label]="translationService.activeTranslation.nextMonth" [attr.aria-disabled]="_canNavigateForward ? null : true" [noDecoration]="true" (click)="_changeMonth(1)" @@ -34,7 +34,7 @@ [usePopover]="usePopover" [selectedIndex]="navigatedYear" [items]="navigableYears" - [attr.aria-label]="translationService.currentTranslation.selectYear" + [attr.aria-label]="translationService.activeTranslation.selectYear" popout="left" (change)="_changeYear($event)" > diff --git a/libs/designsystem/shared/src/translation/translation.interface.ts b/libs/designsystem/shared/src/translation/translation.interface.ts index 77d671b16e..aee11e5b41 100644 --- a/libs/designsystem/shared/src/translation/translation.interface.ts +++ b/libs/designsystem/shared/src/translation/translation.interface.ts @@ -1,4 +1,5 @@ export interface Translation { + $code: string; back: string; close: string; nextMonth: string; diff --git a/libs/designsystem/shared/src/translation/translation.service.ts b/libs/designsystem/shared/src/translation/translation.service.ts index d39ff8ec39..8afb5edfd8 100644 --- a/libs/designsystem/shared/src/translation/translation.service.ts +++ b/libs/designsystem/shared/src/translation/translation.service.ts @@ -13,21 +13,23 @@ export class TranslationService { en, }; - public currentTranslation: Translation = en; + public activeTranslation: Translation = en; constructor(@Inject(LOCALE_ID) private localeId: string) { - this.setCurrentTranslation(localeId); + this.setTranslation(localeId); } - setCurrentTranslation(localeId: string): string { + setTranslation(localeId: string): string { const baseLocaleId = localeId.split('-')[0]; const translation = this.translations[baseLocaleId]; if (!translation) { - console.warn(`Translation not found for locale "${this.localeId}", falling back to "en"`); + console.warn( + `Translation not found for locale "${this.localeId}", falling back to ${this.activeTranslation.$code}` + ); return; } - this.currentTranslation = translation; + this.activeTranslation = translation; } } diff --git a/libs/designsystem/shared/src/translation/translations/da.ts b/libs/designsystem/shared/src/translation/translations/da.ts index 720f565431..cb0cf03017 100644 --- a/libs/designsystem/shared/src/translation/translations/da.ts +++ b/libs/designsystem/shared/src/translation/translations/da.ts @@ -1,6 +1,7 @@ import { Translation } from '../translation.interface'; export const da: Translation = { + $code: 'da', back: 'Tilbage', close: 'Luk', nextMonth: 'Næste måned', diff --git a/libs/designsystem/shared/src/translation/translations/en.ts b/libs/designsystem/shared/src/translation/translations/en.ts index e36ef5b0ca..23bc39e415 100644 --- a/libs/designsystem/shared/src/translation/translations/en.ts +++ b/libs/designsystem/shared/src/translation/translations/en.ts @@ -1,6 +1,7 @@ import { Translation } from '../translation.interface'; export const en: Translation = { + $code: 'en', back: 'Back', close: 'Close', nextMonth: 'Next month', From da3629b4676d16a81e123150264fe9edb529c818 Mon Sep 17 00:00:00 2001 From: RasmusKjeldgaard Date: Fri, 22 Nov 2024 11:25:38 +0100 Subject: [PATCH 04/19] Simplify syntax for getting translated values --- libs/designsystem/calendar/src/calendar.component.html | 6 +++--- libs/designsystem/calendar/src/calendar.component.ts | 2 +- .../shared/src/translation/translation.service.ts | 8 ++++++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/libs/designsystem/calendar/src/calendar.component.html b/libs/designsystem/calendar/src/calendar.component.html index ab03bcbfac..9870812dcc 100644 --- a/libs/designsystem/calendar/src/calendar.component.html +++ b/libs/designsystem/calendar/src/calendar.component.html @@ -4,7 +4,7 @@ kirby-button type="button" class="no-margin" - [attr.aria-label]="translationService.activeTranslation.previousMonth" + [attr.aria-label]="translations.get('previousMonth')" [attr.aria-disabled]="_canNavigateBack ? null : true" [noDecoration]="true" (click)="_changeMonth(-1)" @@ -21,7 +21,7 @@ kirby-button type="button" class="no-margin" - [attr.aria-label]="translationService.activeTranslation.nextMonth" + [attr.aria-label]="translations.get('nextMonth')" [attr.aria-disabled]="_canNavigateForward ? null : true" [noDecoration]="true" (click)="_changeMonth(1)" @@ -34,7 +34,7 @@ [usePopover]="usePopover" [selectedIndex]="navigatedYear" [items]="navigableYears" - [attr.aria-label]="translationService.activeTranslation.selectYear" + [attr.aria-label]="translations.get('selectYear')" popout="left" (change)="_changeYear($event)" > diff --git a/libs/designsystem/calendar/src/calendar.component.ts b/libs/designsystem/calendar/src/calendar.component.ts index 669467751f..de25c70fad 100644 --- a/libs/designsystem/calendar/src/calendar.component.ts +++ b/libs/designsystem/calendar/src/calendar.component.ts @@ -225,7 +225,7 @@ export class CalendarComponent implements OnInit, OnChanges { @Inject(LOCALE_ID) locale: string, private elementRef: ElementRef, private cdr: ChangeDetectorRef, - public translationService: TranslationService + public translations: TranslationService ) { this.locale = this.mapLocale(locale); this.timeZoneName = Intl.DateTimeFormat().resolvedOptions().timeZone; diff --git a/libs/designsystem/shared/src/translation/translation.service.ts b/libs/designsystem/shared/src/translation/translation.service.ts index 8afb5edfd8..f32b4b8315 100644 --- a/libs/designsystem/shared/src/translation/translation.service.ts +++ b/libs/designsystem/shared/src/translation/translation.service.ts @@ -13,7 +13,7 @@ export class TranslationService { en, }; - public activeTranslation: Translation = en; + private activeTranslation: Translation = en; constructor(@Inject(LOCALE_ID) private localeId: string) { this.setTranslation(localeId); @@ -25,11 +25,15 @@ export class TranslationService { if (!translation) { console.warn( - `Translation not found for locale "${this.localeId}", falling back to ${this.activeTranslation.$code}` + `Translation not found for locale "${this.localeId}", falling back to ${this.get('$code')}` ); return; } this.activeTranslation = translation; } + + get(key: keyof Translation): string { + return this.activeTranslation[key]; + } } From faa0d78b31d8a1def738a69371ddb9657f2ba751 Mon Sep 17 00:00:00 2001 From: RasmusKjeldgaard Date: Sat, 23 Nov 2024 23:16:20 +0100 Subject: [PATCH 05/19] Add missing translations --- .../modal/src/modal-wrapper/modal-wrapper.component.html | 1 + .../modal/src/modal-wrapper/modal-wrapper.component.ts | 5 +++-- libs/designsystem/page/src/page.component.html | 3 ++- libs/designsystem/page/src/page.component.ts | 9 +++++++-- libs/designsystem/slide/src/slides.component.ts | 8 +++++++- 5 files changed, 20 insertions(+), 6 deletions(-) diff --git a/libs/designsystem/modal/src/modal-wrapper/modal-wrapper.component.html b/libs/designsystem/modal/src/modal-wrapper/modal-wrapper.component.html index 2a44126ede..152738d491 100644 --- a/libs/designsystem/modal/src/modal-wrapper/modal-wrapper.component.html +++ b/libs/designsystem/modal/src/modal-wrapper/modal-wrapper.component.html @@ -20,6 +20,7 @@ attentionLevel="3" size="md" [noDecoration]="config.interactWithBackground" + [attr.aria-label]="translations.get('close')" (click)="close()" > diff --git a/libs/designsystem/modal/src/modal-wrapper/modal-wrapper.component.ts b/libs/designsystem/modal/src/modal-wrapper/modal-wrapper.component.ts index 99004e462f..8a30eb0057 100644 --- a/libs/designsystem/modal/src/modal-wrapper/modal-wrapper.component.ts +++ b/libs/designsystem/modal/src/modal-wrapper/modal-wrapper.component.ts @@ -25,7 +25,7 @@ import { debounceTime, first, map, takeUntil } from 'rxjs/operators'; import { DesignTokenHelper } from '@kirbydesign/designsystem/helpers'; -import { ResizeObserverService } from '@kirbydesign/designsystem/shared'; +import { ResizeObserverService, TranslationService } from '@kirbydesign/designsystem/shared'; import { WindowRef } from '@kirbydesign/designsystem/types'; import { PlatformService } from '@kirbydesign/designsystem/helpers'; import { CommonModule } from '@angular/common'; @@ -174,7 +174,8 @@ export class ModalWrapperComponent private windowRef: WindowRef, private platform: PlatformService, private canDismissHelper: CanDismissHelper, - private environmentInjector: EnvironmentInjector + private environmentInjector: EnvironmentInjector, + public translations: TranslationService ) { this.setViewportHeight(); this.observeViewportResize(); diff --git a/libs/designsystem/page/src/page.component.html b/libs/designsystem/page/src/page.component.html index aa5771e482..7380e05435 100644 --- a/libs/designsystem/page/src/page.component.html +++ b/libs/designsystem/page/src/page.component.html @@ -9,6 +9,7 @@ [defaultHref]="defaultBackHref" icon="assets/kirby/icons/svg/arrow-back.svg" [style.visibility]="hideBackButton ? 'hidden' : null" + [attr.aria-label]="translations.get('back')" > @@ -68,7 +69,7 @@ class="page-header" [ngClass]="{ 'text-center': titleAlignment === 'center', - 'text-right': titleAlignment === 'right' + 'text-right': titleAlignment === 'right', }" >
diff --git a/libs/designsystem/page/src/page.component.ts b/libs/designsystem/page/src/page.component.ts index 3026a6568d..ff6778f261 100644 --- a/libs/designsystem/page/src/page.component.ts +++ b/libs/designsystem/page/src/page.component.ts @@ -60,7 +60,11 @@ import { ModalElementType, ModalNavigationService, } from '@kirbydesign/designsystem/modal'; -import { FitHeadingConfig, ResizeObserverService } from '@kirbydesign/designsystem/shared'; +import { + FitHeadingConfig, + ResizeObserverService, + TranslationService, +} from '@kirbydesign/designsystem/shared'; /** * Specify scroll event debounce time in ms and scrolled offset from top in pixels @@ -364,7 +368,8 @@ export class PageComponent private routerOutlet: IonRouterOutlet, @Optional() private navCtrl: NavController, - private ionicElementPartHelper: IonicElementPartHelper + private ionicElementPartHelper: IonicElementPartHelper, + public translations: TranslationService ) {} private contentReadyPromise: Promise; diff --git a/libs/designsystem/slide/src/slides.component.ts b/libs/designsystem/slide/src/slides.component.ts index 27c99dfdb4..5b3592456e 100644 --- a/libs/designsystem/slide/src/slides.component.ts +++ b/libs/designsystem/slide/src/slides.component.ts @@ -21,6 +21,7 @@ import { PlatformService, UniqueIdGenerator, } from '@kirbydesign/designsystem/helpers'; +import { TranslationService } from '@kirbydesign/designsystem/shared'; import { SlideDirective } from './slide.directive'; // Swiper is not an Angular library, @@ -45,7 +46,8 @@ type SwiperContainer = HTMLElement & { initialize: () => void; swiper: Swiper }; export class SlidesComponent implements OnInit, AfterViewInit, OnChanges { constructor( private platform: PlatformService, - private cdr: ChangeDetectorRef + private cdr: ChangeDetectorRef, + private translations: TranslationService ) {} @ViewChild('swiperContainer') swiperContainer: ElementRef; @@ -126,6 +128,10 @@ export class SlidesComponent implements OnInit, AfterViewInit, OnChanges { }); }, }, + a11y: { + prevSlideMessage: this.translations.get('previousSlide'), + nextSlideMessage: this.translations.get('nextSlide'), + }, }; } From 899c1f83f3f808e87aa3f1965c40665741033462 Mon Sep 17 00:00:00 2001 From: RasmusKjeldgaard Date: Tue, 26 Nov 2024 17:54:23 +0100 Subject: [PATCH 06/19] Add flags for locale avatars in docs --- apps/cookbook/src/assets/images/dk.svg | 5 +++++ apps/cookbook/src/assets/images/us.svg | 10 ++++++++++ 2 files changed, 15 insertions(+) create mode 100644 apps/cookbook/src/assets/images/dk.svg create mode 100644 apps/cookbook/src/assets/images/us.svg diff --git a/apps/cookbook/src/assets/images/dk.svg b/apps/cookbook/src/assets/images/dk.svg new file mode 100644 index 0000000000..563277f81d --- /dev/null +++ b/apps/cookbook/src/assets/images/dk.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/apps/cookbook/src/assets/images/us.svg b/apps/cookbook/src/assets/images/us.svg new file mode 100644 index 0000000000..73b62457c4 --- /dev/null +++ b/apps/cookbook/src/assets/images/us.svg @@ -0,0 +1,10 @@ + + + + + + + + + + From d2afa40df158dacf54719337d34ce35d49ac23c4 Mon Sep 17 00:00:00 2001 From: RasmusKjeldgaard Date: Tue, 26 Nov 2024 17:54:37 +0100 Subject: [PATCH 07/19] Scaffold docs page --- .../da-locale-provider.component.ts | 10 +++ .../en-locale-provider.component.ts | 10 +++ .../localization/localization.component.html | 73 +++++++++++++++++++ .../localization/localization.component.scss | 28 +++++++ .../localization/localization.component.ts | 32 ++++++++ 5 files changed, 153 insertions(+) create mode 100644 apps/cookbook/src/app/localization/locale-provider/da-locale-provider.component.ts create mode 100644 apps/cookbook/src/app/localization/locale-provider/en-locale-provider.component.ts create mode 100644 apps/cookbook/src/app/localization/localization.component.html create mode 100644 apps/cookbook/src/app/localization/localization.component.scss create mode 100644 apps/cookbook/src/app/localization/localization.component.ts diff --git a/apps/cookbook/src/app/localization/locale-provider/da-locale-provider.component.ts b/apps/cookbook/src/app/localization/locale-provider/da-locale-provider.component.ts new file mode 100644 index 0000000000..3ce158551a --- /dev/null +++ b/apps/cookbook/src/app/localization/locale-provider/da-locale-provider.component.ts @@ -0,0 +1,10 @@ +import { Component, LOCALE_ID } from '@angular/core'; +import { TranslationService } from '@kirbydesign/designsystem/shared'; + +@Component({ + selector: 'cookbook-da-locale-provider', + template: '', + standalone: true, + providers: [{ provide: LOCALE_ID, useValue: 'da' }, TranslationService], +}) +export class DaLocaleProviderComponent {} diff --git a/apps/cookbook/src/app/localization/locale-provider/en-locale-provider.component.ts b/apps/cookbook/src/app/localization/locale-provider/en-locale-provider.component.ts new file mode 100644 index 0000000000..77a8ad00c1 --- /dev/null +++ b/apps/cookbook/src/app/localization/locale-provider/en-locale-provider.component.ts @@ -0,0 +1,10 @@ +import { Component, LOCALE_ID } from '@angular/core'; +import { TranslationService } from '@kirbydesign/designsystem/shared'; + +@Component({ + selector: 'cookbook-en-locale-provider', + template: '', + standalone: true, + providers: [{ provide: LOCALE_ID, useValue: 'en' }, TranslationService], +}) +export class EnLocaleProviderComponent {} diff --git a/apps/cookbook/src/app/localization/localization.component.html b/apps/cookbook/src/app/localization/localization.component.html new file mode 100644 index 0000000000..a9b90ebf6d --- /dev/null +++ b/apps/cookbook/src/app/localization/localization.component.html @@ -0,0 +1,73 @@ +
+

Localization

+

+ The Kirby components supports two locales out of the box: English ( + en + ) and Danish ( + da + ). +

+

+ If you need support for other locales, or want to add additional translations, please report an + issue to us on Github, and consider contributing the code to make it happen. Existing + translation files can be found here (link), and registered by adding the translation here + (link). +

+ +

+ Apart from number and date formatting, the main use-case for specifying locale in Kirby is to + provide translations of component internals such as labels. +

+ + +
+
+ + + + + + + + + + + + +
+
+
+ +

Calendar example here.

+ +

Setting Up Translations

+

Define locale in app module.

+ +

Using Translations in Templates

+ Translations are intended for use +

+ Use the + TranslationService + to fetch and display translated strings in your templates. +

+ +

Switching Component Language

+

+ Components are initialized with any locale defined in e.g. the app.module.ts of your projects. + If you want to switch locale at runtime, you can do so by calling + TranslationService.setTranslation('da') + for Danish, or + TranslationService.setTranslation('en') + for English. +

+
diff --git a/apps/cookbook/src/app/localization/localization.component.scss b/apps/cookbook/src/app/localization/localization.component.scss new file mode 100644 index 0000000000..4faf73b207 --- /dev/null +++ b/apps/cookbook/src/app/localization/localization.component.scss @@ -0,0 +1,28 @@ +@use 'sass:map'; +@use '../showcase/showcase.shared'; +@use '@kirbydesign/core/src/scss/utils'; + +$avatar-offset-block-start: -20px; +$avatar-offset-inline-end: -18px; + +:host { + display: block; + container-type: inline-size; +} + +.locale-examples { + display: flex; + justify-content: center; + gap: var(--kirby-spacing-xxxl); + + @container (width < #{map.get(utils.$breakpoints, small)}) { + flex-direction: column; + align-items: center; + } +} + +.locale-avatar { + position: absolute; + inset-block-start: $avatar-offset-block-start; + inset-inline-end: $avatar-offset-inline-end; +} diff --git a/apps/cookbook/src/app/localization/localization.component.ts b/apps/cookbook/src/app/localization/localization.component.ts new file mode 100644 index 0000000000..8a2f72672e --- /dev/null +++ b/apps/cookbook/src/app/localization/localization.component.ts @@ -0,0 +1,32 @@ +import { Component } from '@angular/core'; + +import { CardModule } from '@kirbydesign/designsystem/card'; +import { CalendarComponent } from '@kirbydesign/designsystem/calendar'; +import { TranslationService } from '@kirbydesign/designsystem/shared'; +import { AvatarComponent } from '@kirbydesign/designsystem/avatar'; +import { CodeViewerModule } from '../shared/code-viewer/code-viewer.module'; +import { ExamplesModule } from '../examples/examples.module'; +import { ShowcaseModule } from '../showcase/showcase.module'; +import { DaLocaleProviderComponent } from './locale-provider/da-locale-provider.component'; +import { EnLocaleProviderComponent } from './locale-provider/en-locale-provider.component'; + +@Component({ + selector: 'cookbook-localization', + templateUrl: './localization.component.html', + styleUrls: ['./localization.component.scss'], + standalone: true, + imports: [ + CodeViewerModule, + ShowcaseModule, + ExamplesModule, + DaLocaleProviderComponent, + EnLocaleProviderComponent, + CalendarComponent, + CardModule, + AvatarComponent, + ], +}) +export class LocalizationComponent { + constructor(public translations: TranslationService) {} + selectedDate: Date = new Date(2025, 0, 1); +} From 52f47fa4d18fe2db294f0e51d2755e0a3e4aef2a Mon Sep 17 00:00:00 2001 From: RasmusKjeldgaard Date: Tue, 26 Nov 2024 17:55:36 +0100 Subject: [PATCH 08/19] Replace us flag with gb --- apps/cookbook/src/assets/images/gb.svg | 7 +++++++ apps/cookbook/src/assets/images/us.svg | 10 ---------- 2 files changed, 7 insertions(+), 10 deletions(-) create mode 100644 apps/cookbook/src/assets/images/gb.svg delete mode 100644 apps/cookbook/src/assets/images/us.svg diff --git a/apps/cookbook/src/assets/images/gb.svg b/apps/cookbook/src/assets/images/gb.svg new file mode 100644 index 0000000000..dbac25eae4 --- /dev/null +++ b/apps/cookbook/src/assets/images/gb.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/apps/cookbook/src/assets/images/us.svg b/apps/cookbook/src/assets/images/us.svg deleted file mode 100644 index 73b62457c4..0000000000 --- a/apps/cookbook/src/assets/images/us.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - From bd85508005e8be2e8ff10b967ac3c6fee4879cce Mon Sep 17 00:00:00 2001 From: RasmusKjeldgaard Date: Tue, 26 Nov 2024 17:56:16 +0100 Subject: [PATCH 09/19] Add localization route --- apps/cookbook/src/app/app.routes.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/cookbook/src/app/app.routes.ts b/apps/cookbook/src/app/app.routes.ts index 8427daf7cc..8604124bd6 100644 --- a/apps/cookbook/src/app/app.routes.ts +++ b/apps/cookbook/src/app/app.routes.ts @@ -5,6 +5,7 @@ import { ComponentOverviewComponent } from './component-overview/component-overv import { HomeComponent } from './home/home.component'; import { IntroComponent } from './intro/intro.component'; import { ExtensionsLandingPageComponent } from './extensions/extensions-landing-page.component'; +import { LocalizationComponent } from './localization/localization.component'; export const routes: Routes = [ { @@ -45,6 +46,10 @@ export const routes: Routes = [ path: 'extensions', component: ExtensionsLandingPageComponent, }, + { + path: 'localization', + component: LocalizationComponent, + }, ], }, { From 316c44d1c5261791324a8e8b5d240ea19f22231b Mon Sep 17 00:00:00 2001 From: RasmusKjeldgaard Date: Tue, 3 Dec 2024 12:26:33 +0100 Subject: [PATCH 10/19] Improve wording --- .../shared/src/translation/translation.service.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/libs/designsystem/shared/src/translation/translation.service.ts b/libs/designsystem/shared/src/translation/translation.service.ts index f32b4b8315..7efa64ef65 100644 --- a/libs/designsystem/shared/src/translation/translation.service.ts +++ b/libs/designsystem/shared/src/translation/translation.service.ts @@ -8,24 +8,20 @@ import { Translation } from './translation.interface'; providedIn: 'root', }) export class TranslationService { - private translations: { [key: string]: Translation } = { - da, - en, - }; - private activeTranslation: Translation = en; + private translations: { [key: string]: Translation } = { da, en }; constructor(@Inject(LOCALE_ID) private localeId: string) { - this.setTranslation(localeId); + this.setActiveTranslation(localeId); } - setTranslation(localeId: string): string { + private setActiveTranslation(localeId: string): string { const baseLocaleId = localeId.split('-')[0]; const translation = this.translations[baseLocaleId]; if (!translation) { console.warn( - `Translation not found for locale "${this.localeId}", falling back to ${this.get('$code')}` + `[Kirby] Internal component translations were not found for locale "${this.localeId}", falling back to ${this.get('$code')}` ); return; } From 85b770cc5d93f1a675688b758b3a8d1e31e74a5d Mon Sep 17 00:00:00 2001 From: RasmusKjeldgaard Date: Tue, 3 Dec 2024 15:19:43 +0100 Subject: [PATCH 11/19] Restructure docs --- .../localization/localization.component.html | 73 ++++++++++++------- .../localization/localization.component.scss | 4 +- .../localization/localization.component.ts | 19 +++++ 3 files changed, 69 insertions(+), 27 deletions(-) diff --git a/apps/cookbook/src/app/localization/localization.component.html b/apps/cookbook/src/app/localization/localization.component.html index a9b90ebf6d..9011b9ca1b 100644 --- a/apps/cookbook/src/app/localization/localization.component.html +++ b/apps/cookbook/src/app/localization/localization.component.html @@ -1,22 +1,30 @@

Localization

- The Kirby components supports two locales out of the box: English ( - en + Locale information is used by components such as + kirby-calendar + and + input type="date" + to automatically format values according to locale. Support has been added for three locales out + of the box: American English ( + en-US + ), British English ( + en-GB ) and Danish ( da ).

- If you need support for other locales, or want to add additional translations, please report an - issue to us on Github, and consider contributing the code to make it happen. Existing - translation files can be found here (link), and registered by adding the translation here - (link). + Specifying the locale will also ensure translation of + internal + component labels and texts that are not configurable. This allows assistive technology such as + screen readers to announce labels in the correct language.

- Apart from number and date formatting, the main use-case for specifying locale in Kirby is to - provide translations of component internals such as labels. + In this example visible information such as the month and weekday headers, and accessible names + for headers, calendar cells and interactive buttons have been automatically translated by + specifying the locale.

@@ -48,26 +56,41 @@

Localization

-

Calendar example here.

- -

Setting Up Translations

-

Define locale in app module.

- -

Using Translations in Templates

- Translations are intended for use +

Additional locales

- Use the + If support for other locales or additional translations are needed please + + create an enhancement issue on Github + and consider contributing the code to make it happen. Please refer to the + + existing translation files + + and how + + translation registering + + is done in the TranslationService - to fetch and display translated strings in your templates. + . +

+

Using translated values directly

+

+ If custom components are closely coupled to Kirby and need to use identical translations the + TranslationService + can be used to fetch and display translated strings.

- -

Switching Component Language

- Components are initialized with any locale defined in e.g. the app.module.ts of your projects. - If you want to switch locale at runtime, you can do so by calling - TranslationService.setTranslation('da') - for Danish, or - TranslationService.setTranslation('en') - for English. + This can be done by injecting the service and getting any key defined in the + + Translation + + interface.

+ diff --git a/apps/cookbook/src/app/localization/localization.component.scss b/apps/cookbook/src/app/localization/localization.component.scss index 4faf73b207..3b7251ff08 100644 --- a/apps/cookbook/src/app/localization/localization.component.scss +++ b/apps/cookbook/src/app/localization/localization.component.scss @@ -2,8 +2,8 @@ @use '../showcase/showcase.shared'; @use '@kirbydesign/core/src/scss/utils'; -$avatar-offset-block-start: -20px; -$avatar-offset-inline-end: -18px; +$avatar-offset-block-start: -1 * utils.size('s'); +$avatar-offset-inline-end: -1 * utils.size('s'); :host { display: block; diff --git a/apps/cookbook/src/app/localization/localization.component.ts b/apps/cookbook/src/app/localization/localization.component.ts index 8a2f72672e..490235ac44 100644 --- a/apps/cookbook/src/app/localization/localization.component.ts +++ b/apps/cookbook/src/app/localization/localization.component.ts @@ -27,6 +27,25 @@ import { EnLocaleProviderComponent } from './locale-provider/en-locale-provider. ], }) export class LocalizationComponent { + localeConfigCodeSnippet = `import { registerLocaleData } from '@angular/common'; +import localeData from '@angular/common/locales/da'; +import { LOCALE_ID, NgModule } from '@angular/core'; + +registerLocaleData(localeData); + +@NgModule({ + ..., + providers: [ + { provide: LOCALE_ID, useValue: 'da' }, + ], +}) +export class AppModule {}`; + translationGetterCodeSnippet = `constructor(private translationService: TranslationService) {} + +get previousMonthLabel(): string { + return this.translationService.get('previousMonth'); +}`; + constructor(public translations: TranslationService) {} selectedDate: Date = new Date(2025, 0, 1); } From e0d89abb96d43b16c014fd75f4cef4a7f01921cc Mon Sep 17 00:00:00 2001 From: RasmusKjeldgaard Date: Tue, 3 Dec 2024 16:28:07 +0100 Subject: [PATCH 12/19] Add tests --- .../translation/translation.service.spec.ts | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 libs/designsystem/shared/src/translation/translation.service.spec.ts diff --git a/libs/designsystem/shared/src/translation/translation.service.spec.ts b/libs/designsystem/shared/src/translation/translation.service.spec.ts new file mode 100644 index 0000000000..171c8c5686 --- /dev/null +++ b/libs/designsystem/shared/src/translation/translation.service.spec.ts @@ -0,0 +1,47 @@ +import { createServiceFactory, SpectatorService } from '@ngneat/spectator'; +import { LOCALE_ID } from '@angular/core'; +import { TranslationService } from './translation.service'; +import { en } from './translations/en'; +import { da } from './translations/da'; +import { Translation } from './translation.interface'; + +describe('TranslationService', () => { + let spectator: SpectatorService; + const createService = createServiceFactory({ + service: TranslationService, + providers: [{ provide: LOCALE_ID, useValue: 'en' }], + }); + + it('should be created', () => { + spectator = createService(); + expect(spectator.service).toBeTruthy(); + }); + + it('should set active translation based on locale', () => { + spectator = createService(); + expect(spectator.service.get('$code')).toBe(en.$code); + }); + + it('should fall back to default translation if locale is not found', () => { + spectator = createService({ + providers: [{ provide: LOCALE_ID, useValue: 'fr' }], + }); + expect(spectator.service.get('$code')).toBe(en.$code); + }); + + it('should return all translations correctly for da key', () => { + spectator = createService({ providers: [{ provide: LOCALE_ID, useValue: 'da' }] }); + + Object.keys(da).forEach((key: keyof Translation) => { + expect(spectator.service.get(key)).toBe(da[key]); + }); + }); + + it('should return all translations correctly for en key', () => { + spectator = createService({ providers: [{ provide: LOCALE_ID, useValue: 'en' }] }); + + Object.keys(en).forEach((key: keyof Translation) => { + expect(spectator.service.get(key)).toBe(en[key]); + }); + }); +}); From 1a1662f92046d84c82a54d02d83a1862aa8da6a3 Mon Sep 17 00:00:00 2001 From: RasmusKjeldgaard Date: Tue, 3 Dec 2024 16:35:39 +0100 Subject: [PATCH 13/19] Add localization docs to resource links --- apps/cookbook/src/app/app.routes.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/cookbook/src/app/app.routes.ts b/apps/cookbook/src/app/app.routes.ts index 881b6706f2..98d0d22f1b 100644 --- a/apps/cookbook/src/app/app.routes.ts +++ b/apps/cookbook/src/app/app.routes.ts @@ -61,6 +61,9 @@ export const routes: Routes = [ { path: 'localization', component: LocalizationComponent, + data: { + resourceLink: 'Localization', + }, }, ], }, From d02784138e88955f811e9d51bbc8812e69d8b8e1 Mon Sep 17 00:00:00 2001 From: RasmusKjeldgaard Date: Tue, 3 Dec 2024 16:38:16 +0100 Subject: [PATCH 14/19] Switch sections around --- .../localization/localization.component.html | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/apps/cookbook/src/app/localization/localization.component.html b/apps/cookbook/src/app/localization/localization.component.html index 9011b9ca1b..5fd87fd3a5 100644 --- a/apps/cookbook/src/app/localization/localization.component.html +++ b/apps/cookbook/src/app/localization/localization.component.html @@ -56,6 +56,23 @@

Localization

+

Using the service directly

+

+ If custom components are closely coupled to Kirby and need to use identical translations, + TranslationService + can be used to fetch and display translated strings. +

+

+ This can be done by injecting the service and getting any key defined in the + + Translation + + interface. +

+ +

Additional locales

If support for other locales or additional translations are needed please @@ -77,20 +94,4 @@

Additional locales

TranslationService .

-

Using translated values directly

-

- If custom components are closely coupled to Kirby and need to use identical translations the - TranslationService - can be used to fetch and display translated strings. -

-

- This can be done by injecting the service and getting any key defined in the - - Translation - - interface. -

- From 47f7afacf72aebb21de48eedd19eb179833ff52b Mon Sep 17 00:00:00 2001 From: RasmusKjeldgaard Date: Tue, 3 Dec 2024 16:42:07 +0100 Subject: [PATCH 15/19] Simplify values --- .../src/app/localization/localization.component.scss | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/apps/cookbook/src/app/localization/localization.component.scss b/apps/cookbook/src/app/localization/localization.component.scss index 3b7251ff08..b8f1df896d 100644 --- a/apps/cookbook/src/app/localization/localization.component.scss +++ b/apps/cookbook/src/app/localization/localization.component.scss @@ -2,8 +2,7 @@ @use '../showcase/showcase.shared'; @use '@kirbydesign/core/src/scss/utils'; -$avatar-offset-block-start: -1 * utils.size('s'); -$avatar-offset-inline-end: -1 * utils.size('s'); +$avatar-offset: -1 * utils.size('s'); :host { display: block; @@ -23,6 +22,5 @@ $avatar-offset-inline-end: -1 * utils.size('s'); .locale-avatar { position: absolute; - inset-block-start: $avatar-offset-block-start; - inset-inline-end: $avatar-offset-inline-end; + inset: $avatar-offset $avatar-offset auto auto; } From 9281721e84fe6b0081ae21404f4d9c96e2dded7b Mon Sep 17 00:00:00 2001 From: RasmusKjeldgaard Date: Wed, 4 Dec 2024 09:22:33 +0100 Subject: [PATCH 16/19] Use relative asset urls --- .../cookbook/src/app/localization/localization.component.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/cookbook/src/app/localization/localization.component.html b/apps/cookbook/src/app/localization/localization.component.html index 5fd87fd3a5..ed7cdaa5fd 100644 --- a/apps/cookbook/src/app/localization/localization.component.html +++ b/apps/cookbook/src/app/localization/localization.component.html @@ -37,7 +37,7 @@

Localization

@@ -48,7 +48,7 @@

Localization

From 90462c651c1c712ba2f77b7a69c01594566892a3 Mon Sep 17 00:00:00 2001 From: RasmusKjeldgaard Date: Wed, 4 Dec 2024 11:01:00 +0100 Subject: [PATCH 17/19] Docs readability Co-authored-by: Jakob Engelbrecht --- .../cookbook/src/app/localization/localization.component.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/cookbook/src/app/localization/localization.component.html b/apps/cookbook/src/app/localization/localization.component.html index ed7cdaa5fd..f1a488827c 100644 --- a/apps/cookbook/src/app/localization/localization.component.html +++ b/apps/cookbook/src/app/localization/localization.component.html @@ -58,12 +58,12 @@

Localization

Using the service directly

- If custom components are closely coupled to Kirby and need to use identical translations, + When developing custom components closely coupled to Kirby that need to use identical translations, TranslationService can be used to fetch and display translated strings.

- This can be done by injecting the service and getting any key defined in the + This can be done by injecting the service into the component and get any key defined in the From 8b4c172a0cd19c72501f3f29e1519e8889f8edc0 Mon Sep 17 00:00:00 2001 From: RasmusKjeldgaard Date: Wed, 4 Dec 2024 11:08:22 +0100 Subject: [PATCH 18/19] Move inline style --- .../cookbook/src/app/localization/localization.component.html | 4 ++-- .../cookbook/src/app/localization/localization.component.scss | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/apps/cookbook/src/app/localization/localization.component.html b/apps/cookbook/src/app/localization/localization.component.html index f1a488827c..dc07efa8ee 100644 --- a/apps/cookbook/src/app/localization/localization.component.html +++ b/apps/cookbook/src/app/localization/localization.component.html @@ -30,7 +30,7 @@

Localization

- + @@ -41,7 +41,7 @@

Localization

altText="Danish locale" >
- + diff --git a/apps/cookbook/src/app/localization/localization.component.scss b/apps/cookbook/src/app/localization/localization.component.scss index b8f1df896d..b9adbc847a 100644 --- a/apps/cookbook/src/app/localization/localization.component.scss +++ b/apps/cookbook/src/app/localization/localization.component.scss @@ -7,6 +7,10 @@ $avatar-offset: -1 * utils.size('s'); :host { display: block; container-type: inline-size; + + :has(> .locale-avatar) { + position: relative; + } } .locale-examples { From f8bb338ae6bc536cead8fa9a6a0d830ac4cca4b6 Mon Sep 17 00:00:00 2001 From: RasmusKjeldgaard Date: Wed, 4 Dec 2024 11:16:06 +0100 Subject: [PATCH 19/19] Show config code snippet --- .../app/localization/localization.component.html | 13 ++++++++++++- .../app/localization/localization.component.scss | 4 ++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/apps/cookbook/src/app/localization/localization.component.html b/apps/cookbook/src/app/localization/localization.component.html index dc07efa8ee..f8fa49d465 100644 --- a/apps/cookbook/src/app/localization/localization.component.html +++ b/apps/cookbook/src/app/localization/localization.component.html @@ -14,6 +14,16 @@

Localization

da ).

+ +

+ Locale is usually configured for the entire app in the + AppModule + . +

+

Specifying the locale will also ensure translation of internal @@ -58,7 +68,8 @@

Localization

Using the service directly

- When developing custom components closely coupled to Kirby that need to use identical translations, + When developing custom components closely coupled to Kirby that need to use identical + translations, TranslationService can be used to fetch and display translated strings.

diff --git a/apps/cookbook/src/app/localization/localization.component.scss b/apps/cookbook/src/app/localization/localization.component.scss index b9adbc847a..54ddc19891 100644 --- a/apps/cookbook/src/app/localization/localization.component.scss +++ b/apps/cookbook/src/app/localization/localization.component.scss @@ -28,3 +28,7 @@ $avatar-offset: -1 * utils.size('s'); position: absolute; inset: $avatar-offset $avatar-offset auto auto; } + +.code-only-example { + margin-block-end: utils.size('s'); +}