From 1e19dd3193f46771ab855dbdd342fe25ac9b2e41 Mon Sep 17 00:00:00 2001 From: Marcin Stelmaszyk Date: Tue, 13 May 2025 08:07:33 +0200 Subject: [PATCH 1/9] Reapply "feat: enable light mode (#255)" (#443) This reverts commit 3be6ade501e8cae1d4aed3131db96b3dc6bdc21c. --- apps/blog/src/assets/icons/arrow-down.svg | 2 +- .../feature-about-us.component.html | 6 +- .../feature-latest-articles.component.ts | 1 - .../article-compact-card.component.html | 19 +- .../article-compact-card.component.ts | 11 +- .../article-hero-card-skeleton.component.ts | 2 +- .../article-horizontal-card.component.html | 2 +- .../article-regular-card.component.html | 18 +- .../ui-article-card.component.html | 5 +- .../ui-article-list-title.component.html | 2 +- .../author-card-template.component.ts | 5 +- .../author-card/author-card.component.html | 2 +- .../become-author-page.component.html | 4 +- .../become-author-list-item.component.html | 6 +- .../components/footer-logo.component.ts | 9 +- .../footer-social-media-icons.component.ts | 2 +- .../src/lib/footer/footer.component.html | 13 +- .../src/lib/footer/footer.component.scss | 18 +- .../lib/navigation/navigation.component.html | 8 +- .../lib/navigation/navigation.component.ts | 1 + .../newsletter.component.html | 2 +- .../partners-list.component.html | 2 +- .../shared/ui-card/src/lib/card.component.ts | 4 +- .../shared/ui-card/src/lib/card.stories.ts | 2 +- .../src/lib/ui-difficulty.component.ts | 11 +- .../shared/ui-pill/src/lib/pill.directive.ts | 2 +- .../src/lib/social-media-icons.component.html | 5 +- .../lib/rules-row/rules-row.component.html | 4 +- libs/shared/assets/src/lib/styles/main.scss | 15 + package.json | 1 + pnpm-lock.yaml | 9530 ++++++++--------- tailwind.preset.js | 26 +- 32 files changed, 4648 insertions(+), 5092 deletions(-) diff --git a/apps/blog/src/assets/icons/arrow-down.svg b/apps/blog/src/assets/icons/arrow-down.svg index e185563a..62a34851 100644 --- a/apps/blog/src/assets/icons/arrow-down.svg +++ b/apps/blog/src/assets/icons/arrow-down.svg @@ -1 +1 @@ - + \ No newline at end of file diff --git a/libs/blog/about-us/feature-about-us/src/lib/feature-about-us/feature-about-us.component.html b/libs/blog/about-us/feature-about-us/src/lib/feature-about-us/feature-about-us.component.html index f4e1957f..871b50e0 100644 --- a/libs/blog/about-us/feature-about-us/src/lib/feature-about-us/feature-about-us.component.html +++ b/libs/blog/about-us/feature-about-us/src/lib/feature-about-us/feature-about-us.component.html @@ -1,9 +1,9 @@ -

+

{{ t('title') }}

- +
-

+

{{ t('authorsTitle') }}

diff --git a/libs/blog/articles/feature-latest-articles/src/lib/feature-latest-articles/feature-latest-articles.component.ts b/libs/blog/articles/feature-latest-articles/src/lib/feature-latest-articles/feature-latest-articles.component.ts index 5663766e..c49e13da 100644 --- a/libs/blog/articles/feature-latest-articles/src/lib/feature-latest-articles/feature-latest-articles.component.ts +++ b/libs/blog/articles/feature-latest-articles/src/lib/feature-latest-articles/feature-latest-articles.component.ts @@ -38,7 +38,6 @@ import { CategoryListItem, injectCategories } from './categories.const'; NgClass, TranslocoDirective, ArticleRegularCardSkeletonComponent, - CardComponent, RepeatDirective, RouterLink, ButtonComponent, diff --git a/libs/blog/articles/ui-article-card/src/lib/components/article-compact-card/article-compact-card.component.html b/libs/blog/articles/ui-article-card/src/lib/components/article-compact-card/article-compact-card.component.html index b640f9a3..bb0deb59 100644 --- a/libs/blog/articles/ui-article-card/src/lib/components/article-compact-card/article-compact-card.component.html +++ b/libs/blog/articles/ui-article-card/src/lib/components/article-compact-card/article-compact-card.component.html @@ -1,16 +1,17 @@
-
+ Post featured image +
diff --git a/libs/blog/articles/ui-article-card/src/lib/components/article-compact-card/article-compact-card.component.ts b/libs/blog/articles/ui-article-card/src/lib/components/article-compact-card/article-compact-card.component.ts index 3a3b38cc..ffe7f561 100644 --- a/libs/blog/articles/ui-article-card/src/lib/components/article-compact-card/article-compact-card.component.ts +++ b/libs/blog/articles/ui-article-card/src/lib/components/article-compact-card/article-compact-card.component.ts @@ -1,3 +1,4 @@ +import { NgOptimizedImage } from '@angular/common'; import { ChangeDetectionStrategy, Component, input } from '@angular/core'; import { RouterLink } from '@angular/router'; import { FastSvgComponent } from '@push-based/ngx-fast-svg'; @@ -9,9 +10,17 @@ import { AvatarComponent } from '@angular-love/blog/shared/ui-avatar'; @Component({ selector: 'al-article-compact-card', changeDetection: ChangeDetectionStrategy.OnPush, - imports: [AvatarComponent, RouterLink, AlLocalizePipe, FastSvgComponent], + standalone: true, + imports: [ + AvatarComponent, + RouterLink, + AlLocalizePipe, + FastSvgComponent, + NgOptimizedImage, + ], templateUrl: './article-compact-card.component.html', }) export class ArticleCompactCardComponent { readonly article = input.required(); + readonly imagePriority = input(null); } diff --git a/libs/blog/articles/ui-article-card/src/lib/components/article-hero-card/article-hero-card-skeleton.component.ts b/libs/blog/articles/ui-article-card/src/lib/components/article-hero-card/article-hero-card-skeleton.component.ts index 9bbe5978..bfc4063b 100644 --- a/libs/blog/articles/ui-article-card/src/lib/components/article-hero-card/article-hero-card-skeleton.component.ts +++ b/libs/blog/articles/ui-article-card/src/lib/components/article-hero-card/article-hero-card-skeleton.component.ts @@ -7,7 +7,7 @@ import { CardComponent } from '@angular-love/blog/shared/ui-card'; selector: 'al-article-hero-card-skeleton', imports: [NgxSkeletonLoaderModule, CardComponent], template: ` - +
diff --git a/libs/blog/articles/ui-article-card/src/lib/components/article-horizontal-card/article-horizontal-card.component.html b/libs/blog/articles/ui-article-card/src/lib/components/article-horizontal-card/article-horizontal-card.component.html index 5e6de07f..43aedf05 100644 --- a/libs/blog/articles/ui-article-card/src/lib/components/article-horizontal-card/article-horizontal-card.component.html +++ b/libs/blog/articles/ui-article-card/src/lib/components/article-horizontal-card/article-horizontal-card.component.html @@ -1,6 +1,6 @@
- - + + {{ article().author.name }}
@@ -34,10 +38,14 @@
-

+

{{ article().title }}

-

+

{{ article().excerpt }}

diff --git a/libs/blog/articles/ui-article-card/src/lib/ui-article-card/ui-article-card.component.html b/libs/blog/articles/ui-article-card/src/lib/ui-article-card/ui-article-card.component.html index 666ac200..262b5f72 100644 --- a/libs/blog/articles/ui-article-card/src/lib/ui-article-card/ui-article-card.component.html +++ b/libs/blog/articles/ui-article-card/src/lib/ui-article-card/ui-article-card.component.html @@ -12,6 +12,9 @@ /> } @case ('compact') { - + } } diff --git a/libs/blog/articles/ui-article-list-title/src/lib/ui-article-list-title/ui-article-list-title.component.html b/libs/blog/articles/ui-article-list-title/src/lib/ui-article-list-title/ui-article-list-title.component.html index 99262fbc..44234e6e 100644 --- a/libs/blog/articles/ui-article-list-title/src/lib/ui-article-list-title/ui-article-list-title.component.html +++ b/libs/blog/articles/ui-article-list-title/src/lib/ui-article-list-title/ui-article-list-title.component.html @@ -1,7 +1,7 @@

{{ title() }}

diff --git a/libs/blog/authors/ui-author-card/src/lib/author-card/author-card-template.component.ts b/libs/blog/authors/ui-author-card/src/lib/author-card/author-card-template.component.ts index 48f8244c..c121d602 100644 --- a/libs/blog/authors/ui-author-card/src/lib/author-card/author-card-template.component.ts +++ b/libs/blog/authors/ui-author-card/src/lib/author-card/author-card-template.component.ts @@ -8,6 +8,7 @@ import { @Component({ selector: 'al-author-card-template', + standalone: true, imports: [CardComponent, CardContentDirective, GradientCardDirective], host: { class: 'block @container', @@ -19,9 +20,11 @@ import { class="@3xl:flex-row @3xl:border-none flex w-full flex-col items-center rounded-lg border" >
diff --git a/libs/blog/authors/ui-author-card/src/lib/author-card/author-card.component.html b/libs/blog/authors/ui-author-card/src/lib/author-card/author-card.component.html index 73b2947d..08807e6b 100644 --- a/libs/blog/authors/ui-author-card/src/lib/author-card/author-card.component.html +++ b/libs/blog/authors/ui-author-card/src/lib/author-card/author-card.component.html @@ -42,7 +42,7 @@
{{ author().name }} diff --git a/libs/blog/become-author/feature-become-author-page/src/lib/become-author-page/become-author-page.component.html b/libs/blog/become-author/feature-become-author-page/src/lib/become-author-page/become-author-page.component.html index 1dc9a2da..355da1d3 100644 --- a/libs/blog/become-author/feature-become-author-page/src/lib/become-author-page/become-author-page.component.html +++ b/libs/blog/become-author/feature-become-author-page/src/lib/become-author-page/become-author-page.component.html @@ -31,7 +31,7 @@

href="https://form.typeform.com/to/Zzf1Girt?typeform-source=angular.love" target="_blank" > -

+

{{ t('becomeAuthorCard.buttonText') }}

@@ -61,7 +61,7 @@

class="bg-al-pink flex h-[46px] w-full items-center justify-center rounded-lg md:w-4/5 lg:w-full" [routerLink]="'/writing-rules' | alLocalize" > -

+

{{ t('articleWritingRules.buttonText') }}

diff --git a/libs/blog/become-author/feature-become-author-page/src/lib/components/become-author-list-item/become-author-list-item.component.html b/libs/blog/become-author/feature-become-author-page/src/lib/components/become-author-list-item/become-author-list-item.component.html index 233a64d4..d9b2544d 100644 --- a/libs/blog/become-author/feature-become-author-page/src/lib/components/become-author-list-item/become-author-list-item.component.html +++ b/libs/blog/become-author/feature-become-author-page/src/lib/components/become-author-list-item/become-author-list-item.component.html @@ -1,18 +1,18 @@
@if (index()) {
-

{{ index() }}

+

{{ index() }}

} @else {
- +
}

diff --git a/libs/blog/layouts/ui-layouts/src/lib/footer/components/footer-logo.component.ts b/libs/blog/layouts/ui-layouts/src/lib/footer/components/footer-logo.component.ts index dee112d7..ea0383de 100644 --- a/libs/blog/layouts/ui-layouts/src/lib/footer/components/footer-logo.component.ts +++ b/libs/blog/layouts/ui-layouts/src/lib/footer/components/footer-logo.component.ts @@ -1,5 +1,5 @@ import { NgOptimizedImage } from '@angular/common'; -import { ChangeDetectionStrategy, Component, input } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; @Component({ selector: 'al-footer-logo', @@ -16,13 +16,8 @@ import { ChangeDetectionStrategy, Component, input } from '@angular/core'; /> angular.love

-

`, changeDetection: ChangeDetectionStrategy.OnPush, }) -export class FooterLogoComponent { - readonly currentYear = input.required(); -} +export class FooterLogoComponent {} diff --git a/libs/blog/layouts/ui-layouts/src/lib/footer/components/footer-social-media-icons.component.ts b/libs/blog/layouts/ui-layouts/src/lib/footer/components/footer-social-media-icons.component.ts index 52137a0c..5f297505 100644 --- a/libs/blog/layouts/ui-layouts/src/lib/footer/components/footer-social-media-icons.component.ts +++ b/libs/blog/layouts/ui-layouts/src/lib/footer/components/footer-social-media-icons.component.ts @@ -9,7 +9,7 @@ import { SocialMediaIconsComponent } from '@angular-love/blog/shared/ui-social-m
diff --git a/libs/blog/layouts/ui-layouts/src/lib/footer/footer.component.html b/libs/blog/layouts/ui-layouts/src/lib/footer/footer.component.html index 02203540..a42c92fd 100644 --- a/libs/blog/layouts/ui-layouts/src/lib/footer/footer.component.html +++ b/libs/blog/layouts/ui-layouts/src/lib/footer/footer.component.html @@ -1,17 +1,16 @@ -
-
diff --git a/libs/blog/authors/ui-author-card/src/lib/author-card/author-card-template.component.ts b/libs/blog/authors/ui-author-card/src/lib/author-card/author-card-template.component.ts index aff147c2..c191a493 100644 --- a/libs/blog/authors/ui-author-card/src/lib/author-card/author-card-template.component.ts +++ b/libs/blog/authors/ui-author-card/src/lib/author-card/author-card-template.component.ts @@ -3,13 +3,12 @@ import { Component } from '@angular/core'; import { CardComponent, CardContentDirective, - GradientCardDirective, } from '@angular-love/blog/shared/ui-card'; @Component({ selector: 'al-author-card-template', standalone: true, - imports: [CardComponent, CardContentDirective, GradientCardDirective], + imports: [CardComponent, CardContentDirective], host: { class: 'block @container', }, @@ -20,11 +19,9 @@ import { class="@3xl:flex-row @3xl:border-none flex w-full flex-col items-center rounded-lg border" >
From 48524396a117512ca11f7084bab46b875d2fee8a Mon Sep 17 00:00:00 2001 From: Marcin Stelmaszyk Date: Mon, 19 May 2025 14:08:47 +0200 Subject: [PATCH 4/9] fix: hamburger-button color --- .../src/lib/header/components/header-hamburger.component.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libs/blog/layouts/ui-layouts/src/lib/header/components/header-hamburger.component.ts b/libs/blog/layouts/ui-layouts/src/lib/header/components/header-hamburger.component.ts index e9b1e27e..42a45b44 100644 --- a/libs/blog/layouts/ui-layouts/src/lib/header/components/header-hamburger.component.ts +++ b/libs/blog/layouts/ui-layouts/src/lib/header/components/header-hamburger.component.ts @@ -19,9 +19,9 @@ import { FastSvgComponent } from '@push-based/ngx-fast-svg'; @if (isOpened()) { } @else { -
-
-
+
+
+
} `, From 31a555a81ac33d3d190276cb183391eb9a80ea5c Mon Sep 17 00:00:00 2001 From: Marcin Stelmaszyk Date: Mon, 19 May 2025 21:24:58 +0200 Subject: [PATCH 5/9] feat: added theme switcher - wip --- apps/blog/src/assets/icons/moon.svg | 1 + apps/blog/src/assets/icons/sun.svg | 1 + .../src/app-theme.store.ts | 25 +++++++++---------- .../src/lib/header/header.component.ts | 23 +++++++++++++++++ .../ui-icon/src/lib/icon/icon.component.ts | 4 ++- .../src/lib/root-shell.component.ts | 11 ++++++++ libs/shared/assets/src/lib/styles/main.scss | 22 ++++++++-------- 7 files changed, 61 insertions(+), 26 deletions(-) create mode 100644 apps/blog/src/assets/icons/moon.svg create mode 100644 apps/blog/src/assets/icons/sun.svg diff --git a/apps/blog/src/assets/icons/moon.svg b/apps/blog/src/assets/icons/moon.svg new file mode 100644 index 00000000..75c6b517 --- /dev/null +++ b/apps/blog/src/assets/icons/moon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/blog/src/assets/icons/sun.svg b/apps/blog/src/assets/icons/sun.svg new file mode 100644 index 00000000..cd8f68d5 --- /dev/null +++ b/apps/blog/src/assets/icons/sun.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/libs/blog/app-theme/data-access-app-theme/src/app-theme.store.ts b/libs/blog/app-theme/data-access-app-theme/src/app-theme.store.ts index c7cdaebe..010ed5f4 100644 --- a/libs/blog/app-theme/data-access-app-theme/src/app-theme.store.ts +++ b/libs/blog/app-theme/data-access-app-theme/src/app-theme.store.ts @@ -1,8 +1,8 @@ import { isPlatformBrowser } from '@angular/common'; import { inject, Injectable, PLATFORM_ID } from '@angular/core'; -import { signalStore, withMethods, withState } from '@ngrx/signals'; +import { patchState, signalStore, withMethods, withState } from '@ngrx/signals'; -type Theme = 'dark' | 'light'; +export type Theme = 'dark' | 'light'; interface AppThemeStore { theme: Theme; @@ -19,9 +19,16 @@ export const AppThemeStore = signalStore( ) => ({ syncWithSystemTheme: () => { if (isPlatformBrowser(platformId)) { - ccConsumer.setThemeClass(getSystemTheme()); + const theme = getSystemTheme(); + ccConsumer.setThemeAttribute(theme); + patchState(store, { theme: theme }); } }, + toggleTheme: () => { + const theme = store.theme() === 'dark' ? 'light' : 'dark'; + ccConsumer.setThemeAttribute(theme); + patchState(store, { theme: theme }); + }, }), ), ); @@ -35,15 +42,7 @@ function getSystemTheme(): Theme { /* todo: create consumer interface and decouple AppThemeStore from CCAppThemeConsumer*/ @Injectable({ providedIn: 'root' }) export class CCAppThemeConsumer { - setThemeClass(theme: Theme): void { - const htmlElement = document.documentElement; - switch (theme) { - case 'dark': - htmlElement.classList.add('cc--darkmode'); - break; - case 'light': - htmlElement.classList.remove('cc--darkmode'); - break; - } + setThemeAttribute(theme: Theme): void { + document.documentElement.setAttribute('data-theme', theme); } } diff --git a/libs/blog/layouts/ui-layouts/src/lib/header/header.component.ts b/libs/blog/layouts/ui-layouts/src/lib/header/header.component.ts index 412f1932..ce5f0172 100644 --- a/libs/blog/layouts/ui-layouts/src/lib/header/header.component.ts +++ b/libs/blog/layouts/ui-layouts/src/lib/header/header.component.ts @@ -1,10 +1,12 @@ import { ChangeDetectionStrategy, Component, + computed, input, output, signal, } from '@angular/core'; +import { FastSvgComponent } from '@push-based/ngx-fast-svg'; import { LanguagePickerComponent, @@ -36,6 +38,19 @@ import { (languageChange)="languageChange.emit($event)" /> + + (); + readonly theme = input.required<'light' | 'dark'>(); protected languageChange = output(); + protected themeToggle = output(); + protected showNav = signal(false); + protected readonly themeSwitchIcon = computed(() => + this.theme() === 'light' ? 'moon' : 'sun', + ); + protected toggleNav(): void { this.showNav.set(!this.showNav()); } diff --git a/libs/blog/shared/ui-icon/src/lib/icon/icon.component.ts b/libs/blog/shared/ui-icon/src/lib/icon/icon.component.ts index 1d26364c..0ed088f2 100644 --- a/libs/blog/shared/ui-icon/src/lib/icon/icon.component.ts +++ b/libs/blog/shared/ui-icon/src/lib/icon/icon.component.ts @@ -18,7 +18,9 @@ export type IconType = | 'send' | 'tick' | 'twitter-x' - | 'youtube'; + | 'youtube' + | 'sun' + | 'moon'; @Component({ selector: 'al-icon', diff --git a/libs/blog/shell/feature-shell-web/src/lib/root-shell.component.ts b/libs/blog/shell/feature-shell-web/src/lib/root-shell.component.ts index bb385e23..d9b791bb 100644 --- a/libs/blog/shell/feature-shell-web/src/lib/root-shell.component.ts +++ b/libs/blog/shell/feature-shell-web/src/lib/root-shell.component.ts @@ -18,6 +18,7 @@ import { AlBannerCarouselComponent, TopBannerComponent, } from '@angular-love/blog/shared/ad-banner'; +import { AppThemeStore } from '@angular-love/data-access-app-theme'; @Component({ selector: 'al-root-shell', @@ -27,7 +28,9 @@ import { @@ -73,6 +76,10 @@ export class RootShellComponent { readonly translocoService = inject(TranslocoService); + private readonly _appThemeStore = inject(AppThemeStore); + + protected readonly theme = computed(() => this._appThemeStore.theme()); + // todo: temporary solution to keep in mind how banner influence the layout protected readonly adBannerVisible = computed(() => false); @@ -94,6 +101,10 @@ export class RootShellComponent { ); } + onThemeToggle() { + this._appThemeStore.toggleTheme(); + } + constructor(viewport: ViewportScroller) { // todo: temporary solution to keep in mind how banner influence the layout effect(() => { diff --git a/libs/shared/assets/src/lib/styles/main.scss b/libs/shared/assets/src/lib/styles/main.scss index fd26265e..83ddb407 100644 --- a/libs/shared/assets/src/lib/styles/main.scss +++ b/libs/shared/assets/src/lib/styles/main.scss @@ -5,7 +5,7 @@ @tailwind utilities; @layer base { - :root { + :root[data-theme='dark'] { --primary: 255 0 106; --foreground: 255 255 255; --primary-foreground: 255 255 255; @@ -16,17 +16,15 @@ --grey: 46 47 59; } - @media (prefers-color-scheme: light) { - :root { - --primary: 213 1 89; - --foreground: 20 21 27; - --primary-foreground: 0 0 0; - --muted: 25 25 25; - --border: 200 200 200; - --card: 255 255 255; - --background: 255 255 255; - --grey: 241 241 241; - } + :root[data-theme='light'] { + --primary: 213 1 89; + --foreground: 20 21 27; + --primary-foreground: 0 0 0; + --muted: 25 25 25; + --border: 200 200 200; + --card: 255 255 255; + --background: 255 255 255; + --grey: 241 241 241; } } From e4aeaa09468117d65d8a39dfb09c818215224d94 Mon Sep 17 00:00:00 2001 From: Marcin Stelmaszyk Date: Thu, 29 May 2025 15:09:34 +0200 Subject: [PATCH 6/9] feat: added theme switch and fixed cookies consent logic --- .../src/app-theme.store.ts | 22 ++++++++++++++----- .../article-content.component.scss | 2 +- .../article-content.component.ts | 1 - .../src/lib/styles/cookies-consent.scss | 2 +- libs/shared/assets/src/lib/styles/main.scss | 9 +++++--- tailwind.preset.js | 20 +---------------- 6 files changed, 26 insertions(+), 30 deletions(-) diff --git a/libs/blog/app-theme/data-access-app-theme/src/app-theme.store.ts b/libs/blog/app-theme/data-access-app-theme/src/app-theme.store.ts index 010ed5f4..6a9085f3 100644 --- a/libs/blog/app-theme/data-access-app-theme/src/app-theme.store.ts +++ b/libs/blog/app-theme/data-access-app-theme/src/app-theme.store.ts @@ -10,7 +10,7 @@ interface AppThemeStore { export const AppThemeStore = signalStore( { providedIn: 'root' }, - withState({ theme: 'light' }), + withState({ theme: 'dark' }), withMethods( ( store, @@ -19,15 +19,19 @@ export const AppThemeStore = signalStore( ) => ({ syncWithSystemTheme: () => { if (isPlatformBrowser(platformId)) { - const theme = getSystemTheme(); + const theme = + (localStorage.getItem('theme') as Theme) ?? getSystemTheme(); ccConsumer.setThemeAttribute(theme); patchState(store, { theme: theme }); } }, toggleTheme: () => { - const theme = store.theme() === 'dark' ? 'light' : 'dark'; - ccConsumer.setThemeAttribute(theme); - patchState(store, { theme: theme }); + if (isPlatformBrowser(platformId)) { + const newTheme = store.theme() === 'dark' ? 'light' : 'dark'; + ccConsumer.setThemeAttribute(newTheme); + localStorage.setItem('theme', newTheme); + patchState(store, { theme: newTheme }); + } }, }), ), @@ -44,5 +48,13 @@ function getSystemTheme(): Theme { export class CCAppThemeConsumer { setThemeAttribute(theme: Theme): void { document.documentElement.setAttribute('data-theme', theme); + + const classList = document.documentElement.classList; + + if (theme === 'dark') { + classList.add('cc--darkmode'); + } else { + classList.remove('cc--darkmode'); + } } } diff --git a/libs/blog/articles/ui-article-content/src/lib/article-content/article-content.component.scss b/libs/blog/articles/ui-article-content/src/lib/article-content/article-content.component.scss index e914d095..4d2429ca 100644 --- a/libs/blog/articles/ui-article-content/src/lib/article-content/article-content.component.scss +++ b/libs/blog/articles/ui-article-content/src/lib/article-content/article-content.component.scss @@ -5,7 +5,7 @@ margin-top: 1.6rem; } -@media (prefers-color-scheme: dark) { +:root[data-theme='dark'] { .shiki, .shiki span { color: var(--shiki-dark) !important; diff --git a/libs/blog/articles/ui-article-content/src/lib/article-content/article-content.component.ts b/libs/blog/articles/ui-article-content/src/lib/article-content/article-content.component.ts index 26a31b44..f4279355 100644 --- a/libs/blog/articles/ui-article-content/src/lib/article-content/article-content.component.ts +++ b/libs/blog/articles/ui-article-content/src/lib/article-content/article-content.component.ts @@ -12,7 +12,6 @@ import { DomSanitizer } from '@angular/platform-browser'; selector: 'al-article-content', templateUrl: './article-content.component.html', styleUrl: './article-content.component.scss', - imports: [], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, }) diff --git a/libs/shared/assets/src/lib/styles/cookies-consent.scss b/libs/shared/assets/src/lib/styles/cookies-consent.scss index 434be9c2..392d7abd 100644 --- a/libs/shared/assets/src/lib/styles/cookies-consent.scss +++ b/libs/shared/assets/src/lib/styles/cookies-consent.scss @@ -17,7 +17,7 @@ /** Also make toggles the same color as the button **/ --cc-toggle-on-bg: var(--cc-btn-primary-bg); - @media (prefers-color-scheme: light) { + :root[data-theme='light'] { --cc-btn-secondary-color: rgba(44, 47, 49, 1); } } diff --git a/libs/shared/assets/src/lib/styles/main.scss b/libs/shared/assets/src/lib/styles/main.scss index 83ddb407..ba60e4ea 100644 --- a/libs/shared/assets/src/lib/styles/main.scss +++ b/libs/shared/assets/src/lib/styles/main.scss @@ -4,6 +4,9 @@ @tailwind components; @tailwind utilities; +@custom-variant dark (&:where([data-theme="dark"], [data-theme="dark"] *)); +@custom-variant light (&:where([data-theme="light"], [data-theme="light"] *)); + @layer base { :root[data-theme='dark'] { --primary: 255 0 106; @@ -21,7 +24,7 @@ --foreground: 20 21 27; --primary-foreground: 0 0 0; --muted: 25 25 25; - --border: 200 200 200; + --border: 229 231 235; --card: 255 255 255; --background: 255 255 255; --grey: 241 241 241; @@ -80,8 +83,8 @@ html { } } -@layer components { +@layer base { .al-link { - @apply text-blue-600 hover:underline; + @apply text-red-500 hover:underline dark:text-blue-400; } } diff --git a/tailwind.preset.js b/tailwind.preset.js index b7b9ec38..d196aaea 100644 --- a/tailwind.preset.js +++ b/tailwind.preset.js @@ -1,11 +1,6 @@ -const { - themeVariants, - prefersLight, - prefersDark, -} = require('tailwindcss-theme-variants'); - /** @type {import('tailwindcss').Config} */ module.exports = { + darkMode: 'selector', theme: { extend: { colors: { @@ -36,17 +31,4 @@ module.exports = { }, }, }, - plugins: [ - require('@tailwindcss/container-queries'), - themeVariants({ - themes: { - light: { - mediaQuery: prefersLight /* "@media (prefers-color-scheme: light)" */, - }, - dark: { - mediaQuery: prefersDark /* "@media (prefers-color-scheme: dark)" */, - }, - }, - }), - ], }; From 9c822c61d570e9c076ef123e3ae896372716e050 Mon Sep 17 00:00:00 2001 From: Marcin Stelmaszyk Date: Thu, 29 May 2025 15:19:18 +0200 Subject: [PATCH 7/9] feat: added theme in gh-giscus component --- .../src/lib/giscus-comments/giscus-comments.component.html | 2 +- .../src/lib/giscus-comments/giscus-comments.component.ts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/libs/blog/articles/feature-comments/src/lib/giscus-comments/giscus-comments.component.html b/libs/blog/articles/feature-comments/src/lib/giscus-comments/giscus-comments.component.html index 40e24724..206552b0 100644 --- a/libs/blog/articles/feature-comments/src/lib/giscus-comments/giscus-comments.component.html +++ b/libs/blog/articles/feature-comments/src/lib/giscus-comments/giscus-comments.component.html @@ -11,7 +11,7 @@ [attr.strict]="config.strict ? '1' : '0'" [attr.emitmetadata]="config.emitMetadata ? '1' : '0'" [attr.inputposition]="config.inputPosition" - [attr.theme]="config.theme" + [attr.theme]="theme()" src="https://giscus.app/client.js" crossorigin="anonymous" async diff --git a/libs/blog/articles/feature-comments/src/lib/giscus-comments/giscus-comments.component.ts b/libs/blog/articles/feature-comments/src/lib/giscus-comments/giscus-comments.component.ts index 41e7dde0..6ceb99df 100644 --- a/libs/blog/articles/feature-comments/src/lib/giscus-comments/giscus-comments.component.ts +++ b/libs/blog/articles/feature-comments/src/lib/giscus-comments/giscus-comments.component.ts @@ -14,10 +14,10 @@ import { GISCUS_CONFIG, provideComments, } from '@angular-love/blog/articles/data-access'; +import { AppThemeStore } from '@angular-love/data-access-app-theme'; @Component({ selector: 'al-giscus-comments', - imports: [], templateUrl: './giscus-comments.component.html', styleUrl: './giscus-comments.component.scss', changeDetection: ChangeDetectionStrategy.OnPush, @@ -30,6 +30,7 @@ import { export class GiscusCommentsComponent { readonly config = inject(GISCUS_CONFIG); readonly translocoService = inject(TranslocoService); + readonly theme = inject(AppThemeStore).theme; readonly lang = toSignal(this.translocoService.langChanges$, { initialValue: this.translocoService.getActiveLang(), From 6b67725cee5f7480962c782fb91c5b07ad4af0c3 Mon Sep 17 00:00:00 2001 From: Marcin Stelmaszyk Date: Wed, 4 Jun 2025 20:52:43 +0200 Subject: [PATCH 8/9] feat: enhance theming support with light/dark variants and gradient options --- .../feature-about-us.component.html | 7 +++++- .../feature-about-us.component.ts | 5 ++++ .../feature-latest-articles.component.html | 2 +- .../author-card-template.component.ts | 25 ++++++++++--------- .../author-card/author-card.component.html | 2 +- .../lib/author-card/author-card.component.ts | 1 + .../footer-social-media-icons.component.ts | 2 +- .../src/lib/button/button.component.ts | 2 +- .../shared/ui-card/src/lib/card.component.ts | 9 ++++--- .../src/lib/social-media-icons.component.html | 2 +- .../src/lib/social-media-icons.component.ts | 20 ++++++++++++++- libs/shared/assets/src/lib/styles/main.scss | 3 --- tailwind.preset.js | 11 ++++++++ 13 files changed, 66 insertions(+), 25 deletions(-) diff --git a/libs/blog/about-us/feature-about-us/src/lib/feature-about-us/feature-about-us.component.html b/libs/blog/about-us/feature-about-us/src/lib/feature-about-us/feature-about-us.component.html index 871b50e0..8e5dc2e7 100644 --- a/libs/blog/about-us/feature-about-us/src/lib/feature-about-us/feature-about-us.component.html +++ b/libs/blog/about-us/feature-about-us/src/lib/feature-about-us/feature-about-us.component.html @@ -41,7 +41,12 @@

@for (author of authorsCards(); track author.slug) { - + @if ($index === noAuthorsInView() - 2) { @defer (on viewport) { diff --git a/libs/blog/about-us/feature-about-us/src/lib/feature-about-us/feature-about-us.component.ts b/libs/blog/about-us/feature-about-us/src/lib/feature-about-us/feature-about-us.component.ts index 7b137778..e0281fed 100644 --- a/libs/blog/about-us/feature-about-us/src/lib/feature-about-us/feature-about-us.component.ts +++ b/libs/blog/about-us/feature-about-us/src/lib/feature-about-us/feature-about-us.component.ts @@ -16,6 +16,7 @@ import { } from '@angular-love/blog/shared/ui-card'; import { InfiniteScrollTriggerDirective } from '@angular-love/blog/shared/ui-pagination'; import { SocialMediaIconsComponent } from '@angular-love/blog/shared/ui-social-media-icons'; +import { AppThemeStore } from '@angular-love/data-access-app-theme'; @Component({ selector: 'al-about-us', @@ -41,6 +42,10 @@ export class FeatureAboutUsComponent implements OnInit { return this.authorsCards()?.length || 0; }); + readonly theme = inject(AppThemeStore).theme; + + readonly hideGradientInAuthorCards = computed(() => this.theme() === 'light'); + private readonly _skip = this._authorListStore.skip; private readonly _total = this._authorListStore.total; private readonly _pageSize = this._authorListStore.pageSize; diff --git a/libs/blog/articles/feature-latest-articles/src/lib/feature-latest-articles/feature-latest-articles.component.html b/libs/blog/articles/feature-latest-articles/src/lib/feature-latest-articles/feature-latest-articles.component.html index 6fadbca0..17802ad0 100644 --- a/libs/blog/articles/feature-latest-articles/src/lib/feature-latest-articles/feature-latest-articles.component.html +++ b/libs/blog/articles/feature-latest-articles/src/lib/feature-latest-articles/feature-latest-articles.component.html @@ -37,7 +37,7 @@
-
diff --git a/libs/blog/authors/ui-author-card/src/lib/author-card/author-card-template.component.ts b/libs/blog/authors/ui-author-card/src/lib/author-card/author-card-template.component.ts index c191a493..99821566 100644 --- a/libs/blog/authors/ui-author-card/src/lib/author-card/author-card-template.component.ts +++ b/libs/blog/authors/ui-author-card/src/lib/author-card/author-card-template.component.ts @@ -1,36 +1,35 @@ -import { Component } from '@angular/core'; +import { Component, input } from '@angular/core'; import { CardComponent, CardContentDirective, + GradientCardDirective, } from '@angular-love/blog/shared/ui-card'; @Component({ selector: 'al-author-card-template', - standalone: true, - imports: [CardComponent, CardContentDirective], + imports: [CardComponent, CardContentDirective, GradientCardDirective], host: { class: 'block @container', }, template: ` - +
- -
+
@@ -38,4 +37,6 @@ import { `, }) -export class AuthorCardTemplateComponent {} +export class AuthorCardTemplateComponent { + hideGradient = input(true); +} diff --git a/libs/blog/authors/ui-author-card/src/lib/author-card/author-card.component.html b/libs/blog/authors/ui-author-card/src/lib/author-card/author-card.component.html index 08807e6b..0ac69c2d 100644 --- a/libs/blog/authors/ui-author-card/src/lib/author-card/author-card.component.html +++ b/libs/blog/authors/ui-author-card/src/lib/author-card/author-card.component.html @@ -1,5 +1,5 @@
- + @if (linkable()) { diff --git a/libs/blog/authors/ui-author-card/src/lib/author-card/author-card.component.ts b/libs/blog/authors/ui-author-card/src/lib/author-card/author-card.component.ts index 5ea18895..755fc34d 100644 --- a/libs/blog/authors/ui-author-card/src/lib/author-card/author-card.component.ts +++ b/libs/blog/authors/ui-author-card/src/lib/author-card/author-card.component.ts @@ -45,6 +45,7 @@ export class AuthorCardComponent { clampText = input(); linkable = input(false); + hideGradient = input(false); descriptionClass = computed( () => 'text-sm' + (this.clampText() ? ' line-clamp-3' : ''), diff --git a/libs/blog/layouts/ui-layouts/src/lib/footer/components/footer-social-media-icons.component.ts b/libs/blog/layouts/ui-layouts/src/lib/footer/components/footer-social-media-icons.component.ts index 5f297505..dcfa03f3 100644 --- a/libs/blog/layouts/ui-layouts/src/lib/footer/components/footer-social-media-icons.component.ts +++ b/libs/blog/layouts/ui-layouts/src/lib/footer/components/footer-social-media-icons.component.ts @@ -13,7 +13,7 @@ import { SocialMediaIconsComponent } from '@angular-love/blog/shared/ui-social-m > Social media

- +
`, changeDetection: ChangeDetectionStrategy.OnPush, diff --git a/libs/blog/shared/ui-button/src/lib/button/button.component.ts b/libs/blog/shared/ui-button/src/lib/button/button.component.ts index eca33edd..c391f3ab 100644 --- a/libs/blog/shared/ui-button/src/lib/button/button.component.ts +++ b/libs/blog/shared/ui-button/src/lib/button/button.component.ts @@ -21,7 +21,7 @@ const buttonVariants = cva( { variants: { variant: >{ - Primary: 'bg-al-primary/90 text-white font-bold uppercase', + Primary: 'bg-al-primary/90 text-white uppercase', Secondary: 'bg-al-background border', Outline: 'border border-al-primary/90 bg-white text-al-primary', Ghost: 'bg-transparent', diff --git a/libs/blog/shared/ui-card/src/lib/card.component.ts b/libs/blog/shared/ui-card/src/lib/card.component.ts index 218f08e1..573bfe20 100644 --- a/libs/blog/shared/ui-card/src/lib/card.component.ts +++ b/libs/blog/shared/ui-card/src/lib/card.component.ts @@ -65,12 +65,15 @@ export class CardLinkableDirective { @Directive({ standalone: true, selector: 'al-card[alGradientCard]', + host: { + '[class.bg-al-radial-gradient]': '!hideGradient()', + }, }) export class GradientCardDirective { + hideGradient = input(false); + @HostBinding('class') - get hostClasses() { - return 'bg-al-radial-gradient dark:bg-al-background'; - } + hostClasses = 'dark:bg-al-background'; } @Directive({ diff --git a/libs/blog/shared/ui-social-media-icons/src/lib/social-media-icons.component.html b/libs/blog/shared/ui-social-media-icons/src/lib/social-media-icons.component.html index f4244a0d..b69855a4 100644 --- a/libs/blog/shared/ui-social-media-icons/src/lib/social-media-icons.component.html +++ b/libs/blog/shared/ui-social-media-icons/src/lib/social-media-icons.component.html @@ -2,7 +2,7 @@ @for (social of socials; track $index) {
  • diff --git a/libs/blog/shared/ui-social-media-icons/src/lib/social-media-icons.component.ts b/libs/blog/shared/ui-social-media-icons/src/lib/social-media-icons.component.ts index 7fcd41e9..fc99d372 100644 --- a/libs/blog/shared/ui-social-media-icons/src/lib/social-media-icons.component.ts +++ b/libs/blog/shared/ui-social-media-icons/src/lib/social-media-icons.component.ts @@ -1,4 +1,10 @@ -import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; +import { + ChangeDetectionStrategy, + Component, + computed, + inject, + input, +} from '@angular/core'; import { TranslocoService } from '@jsverse/transloco'; import { @@ -6,6 +12,8 @@ import { SocialMediaIconItemUi, } from './social-media-icon-item.component'; +export type SocialMediaIconsVariant = 'light' | 'dark' | 'default'; + @Component({ selector: 'al-social-media-icons', templateUrl: './social-media-icons.component.html', @@ -16,6 +24,16 @@ import { export class SocialMediaIconsComponent { private _transloco = inject(TranslocoService); + variant = input('default'); + + readonly iconColorClass = computed(() => { + return this.variant() === 'default' + ? 'ext-al-primary-foreground' + : this.variant() === 'light' + ? 'text-[#fff]' + : 'text-[#000]'; + }); + readonly socials: SocialMediaIconItemUi[] = [ { usernameOrPageId: 'www.angular.love', diff --git a/libs/shared/assets/src/lib/styles/main.scss b/libs/shared/assets/src/lib/styles/main.scss index ba60e4ea..fca628d7 100644 --- a/libs/shared/assets/src/lib/styles/main.scss +++ b/libs/shared/assets/src/lib/styles/main.scss @@ -4,9 +4,6 @@ @tailwind components; @tailwind utilities; -@custom-variant dark (&:where([data-theme="dark"], [data-theme="dark"] *)); -@custom-variant light (&:where([data-theme="light"], [data-theme="light"] *)); - @layer base { :root[data-theme='dark'] { --primary: 255 0 106; diff --git a/tailwind.preset.js b/tailwind.preset.js index d196aaea..a55a5919 100644 --- a/tailwind.preset.js +++ b/tailwind.preset.js @@ -1,3 +1,5 @@ +const { themeVariants } = require('tailwindcss-theme-variants'); + /** @type {import('tailwindcss').Config} */ module.exports = { darkMode: 'selector', @@ -31,4 +33,13 @@ module.exports = { }, }, }, + plugins: [ + function ({ addVariant }) { + addVariant( + 'light', + '&:where([data-theme="light"], [data-theme="light"] *)', + ); + addVariant('dark', '&:where([data-theme="dark"], [data-theme="dark"] *)'); + }, + ], }; From 540834367289b81c8cb3428d3751ff7f4580e92e Mon Sep 17 00:00:00 2001 From: Marcin Stelmaszyk Date: Thu, 5 Jun 2025 12:25:44 +0200 Subject: [PATCH 9/9] fix: typo --- .../src/lib/social-media-icons.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/blog/shared/ui-social-media-icons/src/lib/social-media-icons.component.ts b/libs/blog/shared/ui-social-media-icons/src/lib/social-media-icons.component.ts index fc99d372..c59d4adc 100644 --- a/libs/blog/shared/ui-social-media-icons/src/lib/social-media-icons.component.ts +++ b/libs/blog/shared/ui-social-media-icons/src/lib/social-media-icons.component.ts @@ -28,7 +28,7 @@ export class SocialMediaIconsComponent { readonly iconColorClass = computed(() => { return this.variant() === 'default' - ? 'ext-al-primary-foreground' + ? 'text-al-primary-foreground' : this.variant() === 'light' ? 'text-[#fff]' : 'text-[#000]';