Skip to content

Commit f836c89

Browse files
authored
release/15_10_2025 (#444)
Added light theme with custom color palette and theme toggle. Restructured footer layout with responsive grid and partner logos, enhanced navigation styling. Implemented keyboard navigation with FocusKeyManager, proper ARIA attributes, semantic HTML structure, and ISO 8601 datetime formats for improved accessibility. KAP-298, KAP-315, KAP-335
1 parent f106b85 commit f836c89

File tree

102 files changed

+5390
-5340
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

102 files changed

+5390
-5340
lines changed
8.52 KB
Loading
7.71 KB
Loading

apps/blog/src/assets/i18n/en.json

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,8 @@
99
"recommended": "Recommended Articles",
1010
"angularNews": "Angular News",
1111
"guides": "Guides",
12-
"partners": "Community partners",
13-
"mainPartner": "Main partner",
1412
"angularInDepth": "Angular In Depth",
13+
"articleTypes": "Article types",
1514
"categories": {
1615
"all": "Latest",
1716
"news": "News",
@@ -24,15 +23,27 @@
2423
"home": "Home Page",
2524
"about": "About us",
2625
"meetups": "Angular Meetups",
26+
"guides": "Angular Guides",
27+
"news": "Angular News",
28+
"in_depth": "In-Depth articles",
29+
"partnership": "Let's discuss partnership",
2730
"become_author": "Become an author",
2831
"newsletter": "Angular.letter",
2932
"navLinks": "Navigation links",
3033
"roadmap": "Roadmap",
34+
"toggle_theme": "Toggle theme",
35+
"open_search_dialog": "Open search dialog",
3136
"languagePicker": {
3237
"pl": "Polish",
33-
"en": "English"
38+
"en": "English",
39+
"select_lang": "Select language"
3440
}
3541
},
42+
"footer": {
43+
"mainPartner": "Main partner",
44+
"partners": "Community partners",
45+
"al-description": "This is the place where you can learn Angular, discover best practices, and stay updated with the latest news and trends"
46+
},
3647
"authorPage": {
3748
"posted_by": "Posted by {{name}}"
3849
},
@@ -203,6 +214,7 @@
203214
"registerButtonShortened": "Download"
204215
},
205216
"search": {
217+
"title": "Search articles",
206218
"no-matches": "No recent matches",
207219
"results": "{{total}} results"
208220
},
@@ -218,6 +230,7 @@
218230
"changeLangToEnglish": "Change language to English"
219231
},
220232
"socialLinks": {
233+
"title": "Social media",
221234
"facebook": "Like our Facebook page",
222235
"twitter-x": "Follow us on X (formerly Twitter)",
223236
"linkedIn": "Follow us on LinkedIn",

apps/blog/src/assets/i18n/pl.json

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,8 @@
99
"recommended": "Polecane Artykuły",
1010
"angularNews": "Wiadomości ze świata Angulara",
1111
"guides": "Poradniki",
12-
"partners": "Community partnerzy",
13-
"mainPartner": "Główny partner",
1412
"angularInDepth": "Angular In Depth",
13+
"articleTypes": "Typy artykułów",
1514
"categories": {
1615
"all": "Najnowsze",
1716
"news": "Nowości",
@@ -24,15 +23,27 @@
2423
"home": "Strona Główna",
2524
"about": "O nas",
2625
"meetups": "Angular Meetups",
26+
"guides": "Angular Guides",
27+
"news": "Angular News",
28+
"in_depth": "Artykuły In-Depth",
29+
"partnership": "Porozmawiajmy o partnerstwie",
2730
"become_author": "Zostań autorem",
2831
"newsletter": "Angular.letter",
2932
"navLinks": "Menu",
3033
"roadmap": "Roadmap",
34+
"toggle_theme": "Przełącz motyw",
35+
"open_search_dialog": "Otwórz okno wyszukiwania",
3136
"languagePicker": {
3237
"pl": "Polski",
33-
"en": "Angielski"
38+
"en": "Angielski",
39+
"select_lang": "Wybierz język"
3440
}
3541
},
42+
"footer": {
43+
"partners": "Community partnerzy",
44+
"mainPartner": "Główny partner",
45+
"al-description": "To jest miejsce, w którym możesz nauczyć się Angulara, odkrywać najlepsze praktyki i być na bieżąco z najnowszymi wiadomościami i trendami"
46+
},
3647
"home": {
3748
"latest": "Latest articles"
3849
},
@@ -206,6 +217,7 @@
206217
"registerButtonShortened": "Pobierz"
207218
},
208219
"search": {
220+
"title": "Wyszukiwanie artykułów",
209221
"no-matches": "Brak wyników",
210222
"results": "{{total}} wyników"
211223
},
@@ -221,6 +233,7 @@
221233
"changeLangToEnglish": "Zmień język na angielski"
222234
},
223235
"socialLinks": {
236+
"title": "Media społecznościowe",
224237
"facebook": "Polub nas na Facebooku",
225238
"twitter-x": "Obserwuj nas na X (dawniej Twitter)",
226239
"linkedIn": "Obserwuj nas na LinkedInie",
Lines changed: 1 addition & 1 deletion
Loading
Lines changed: 1 addition & 0 deletions
Loading

apps/blog/src/assets/icons/sun.svg

Lines changed: 1 addition & 0 deletions
Loading

libs/blog/about-us/feature-about-us/src/lib/feature-about-us/feature-about-us.component.html

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<ng-container *transloco="let t; read: 'aboutUsPage'">
2-
<h2 class="py-4 text-[40px] font-bold">
2+
<h2 class="text-al-primary-foreground py-4 text-[40px] font-bold">
33
{{ t('title') }}
44
</h2>
55

6-
<al-card>
6+
<al-card class="bg-transparent">
77
<section
88
alCardContent
99
aria-labelledby="angular-love"
@@ -35,13 +35,18 @@ <h2 class="py-4 text-[40px] font-bold">
3535
<al-newsletter alCardContent />
3636
</al-card>
3737

38-
<h2 class="mb-8 mt-10 text-[40px] font-bold">
38+
<h2 class="text-al-primary-foreground mb-8 mt-10 text-[40px] font-bold">
3939
{{ t('authorsTitle') }}
4040
</h2>
4141
</ng-container>
4242

4343
@for (author of authorsCards(); track author.slug) {
44-
<al-author-card class="mb-6 block" [author]="author" [linkable]="true" />
44+
<al-author-card
45+
class="mb-6 block"
46+
[author]="author"
47+
[linkable]="true"
48+
[hideGradient]="hideGradientInAuthorCards()"
49+
/>
4550

4651
@if ($index === noAuthorsInView() - 2) {
4752
@defer (on viewport) {

libs/blog/about-us/feature-about-us/src/lib/feature-about-us/feature-about-us.component.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
} from '@angular-love/blog/shared/ui-card';
1717
import { InfiniteScrollTriggerDirective } from '@angular-love/blog/shared/ui-pagination';
1818
import { SocialMediaIconsComponent } from '@angular-love/blog/shared/ui-social-media-icons';
19+
import { AppThemeStore } from '@angular-love/data-access-app-theme';
1920

2021
@Component({
2122
selector: 'al-about-us',
@@ -41,6 +42,12 @@ export class FeatureAboutUsComponent implements OnInit {
4142
return this.authorsCards()?.length || 0;
4243
});
4344

45+
private readonly _theme = inject(AppThemeStore).theme;
46+
47+
readonly hideGradientInAuthorCards = computed(
48+
() => this._theme() === 'light',
49+
);
50+
4451
private readonly _skip = this._authorListStore.skip;
4552
private readonly _total = this._authorListStore.total;
4653
private readonly _pageSize = this._authorListStore.pageSize;
Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
import { isPlatformBrowser } from '@angular/common';
22
import { inject, Injectable, PLATFORM_ID } from '@angular/core';
3-
import { signalStore, withMethods, withState } from '@ngrx/signals';
3+
import { patchState, signalStore, withMethods, withState } from '@ngrx/signals';
44

5-
type Theme = 'dark' | 'light';
5+
export type Theme = 'dark' | 'light';
66

77
interface AppThemeStore {
88
theme: Theme;
99
}
1010

1111
export const AppThemeStore = signalStore(
1212
{ providedIn: 'root' },
13-
withState<AppThemeStore>({ theme: 'light' }),
13+
withState<AppThemeStore>({ theme: 'dark' }),
1414
withMethods(
1515
(
1616
store,
@@ -19,31 +19,41 @@ export const AppThemeStore = signalStore(
1919
) => ({
2020
syncWithSystemTheme: () => {
2121
if (isPlatformBrowser(platformId)) {
22-
ccConsumer.setThemeClass(getSystemTheme());
22+
const theme =
23+
(localStorage.getItem('theme') as Theme) ?? getSystemTheme();
24+
ccConsumer.setThemeAttribute(theme);
25+
patchState(store, { theme: theme });
26+
}
27+
},
28+
toggleTheme: () => {
29+
if (isPlatformBrowser(platformId)) {
30+
const newTheme = store.theme() === 'dark' ? 'light' : 'dark';
31+
ccConsumer.setThemeAttribute(newTheme);
32+
localStorage.setItem('theme', newTheme);
33+
patchState(store, { theme: newTheme });
2334
}
2435
},
2536
}),
2637
),
2738
);
2839

2940
function getSystemTheme(): Theme {
30-
return window.matchMedia('(prefers-color-scheme: dark)').matches
31-
? 'dark'
32-
: 'light';
41+
// Hardcoded to 'dark' for now, as per decision.
42+
return 'dark';
3343
}
3444

3545
/* todo: create consumer interface and decouple AppThemeStore from CCAppThemeConsumer*/
3646
@Injectable({ providedIn: 'root' })
3747
export class CCAppThemeConsumer {
38-
setThemeClass(theme: Theme): void {
39-
const htmlElement = document.documentElement;
40-
switch (theme) {
41-
case 'dark':
42-
htmlElement.classList.add('cc--darkmode');
43-
break;
44-
case 'light':
45-
htmlElement.classList.remove('cc--darkmode');
46-
break;
48+
setThemeAttribute(theme: Theme): void {
49+
document.documentElement.setAttribute('data-theme', theme);
50+
51+
const classList = document.documentElement.classList;
52+
53+
if (theme === 'dark') {
54+
classList.add('cc--darkmode');
55+
} else {
56+
classList.remove('cc--darkmode');
4757
}
4858
}
4959
}

0 commit comments

Comments
 (0)