Skip to content

Commit

Permalink
feat: dark/light mode
Browse files Browse the repository at this point in the history
  • Loading branch information
ManuelRauber committed Jan 26, 2024
1 parent 0c5597c commit ac41e73
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 1 deletion.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<button
(click)="darkLightModeStore.mode() === 'light' ? darkLightModeStore.enableDarkMode() : darkLightModeStore.enableLightMode()"
class="flex h-9 w-9 items-center justify-center rounded-lg border border-gray-200 bg-white p-2 text-xs font-medium text-gray-700 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:outline-none focus:ring-2 focus:ring-gray-300 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white dark:focus:ring-gray-500">
<fa-icon [icon]="darkLightModeStore.mode() === 'light' ? faSun : faMoon" size="xl"></fa-icon>
</button>
18 changes: 18 additions & 0 deletions src/app/components/dark-light-mode/dark-light-mode.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { DarkLightModeStore } from '../../stores/dark-light-mode.store';
import { faMoon, faSun } from '@fortawesome/free-solid-svg-icons';

@Component({
selector: 'pap-dark-light-mode',
standalone: true,
imports: [FaIconComponent],
templateUrl: './dark-light-mode.component.html',
styleUrl: './dark-light-mode.component.css',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class DarkLightModeComponent {
protected readonly darkLightModeStore = inject(DarkLightModeStore);
protected readonly faSun = faSun;
protected readonly faMoon = faMoon;
}
3 changes: 3 additions & 0 deletions src/app/components/header/header.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,8 @@
<span class="self-center whitespace-nowrap pl-2 text-2xl font-semibold dark:text-white">Tipis P&P Tools</span>
</div>
</div>
<div class="flex items-center">
<pap-dark-light-mode />
</div>
</div>
</nav>
3 changes: 2 additions & 1 deletion src/app/components/header/header.component.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { faBars, faDiceD20 } from '@fortawesome/free-solid-svg-icons';
import { DarkLightModeComponent } from '../dark-light-mode/dark-light-mode.component';

@Component({
selector: 'pap-header',
standalone: true,
imports: [FaIconComponent],
imports: [FaIconComponent, DarkLightModeComponent],
templateUrl: './header.component.html',
styleUrl: './header.component.css',
changeDetection: ChangeDetectionStrategy.OnPush,
Expand Down
19 changes: 19 additions & 0 deletions src/app/services/dark-light-mode.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { inject, Injectable } from '@angular/core';
import { DOCUMENT } from '@angular/common';

@Injectable({
providedIn: 'root',
})
export class DarkLightModeService {
private readonly document = inject(DOCUMENT);

enableDarkMode(): void {
this.document.body.parentElement!.classList.add('dark');
this.document.body.parentElement!.classList.remove('light');
}

enableLightMode(): void {
this.document.body.parentElement!.classList.add('light');
this.document.body.parentElement!.classList.remove('dark');
}
}
40 changes: 40 additions & 0 deletions src/app/stores/dark-light-mode.store.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { patchState, signalStore, withHooks, withMethods, withState } from '@ngrx/signals';
import { DarkLightModeService } from '../services/dark-light-mode.service';
import { inject } from '@angular/core';

interface DarkLightModeState {
mode: 'dark' | 'light';
}

const storageKey = 'preferred-mode';

export const DarkLightModeStore = signalStore(
{ providedIn: 'root' },
withState<DarkLightModeState>({ mode: 'light' }),
withMethods(store => {
const darkLightModeService = inject(DarkLightModeService);

return {
enableDarkMode: () => {
darkLightModeService.enableDarkMode();
patchState(store, { mode: 'dark' });
localStorage.setItem(storageKey, 'dark');
},
enableLightMode: () => {
darkLightModeService.enableLightMode();
patchState(store, { mode: 'light' });
localStorage.setItem(storageKey, 'light');
},
};
}),
withHooks({
onInit: store => {
const mode = localStorage.getItem(storageKey) ?? 'light';
if (mode === 'light') {
return store.enableLightMode();
}

return store.enableDarkMode();
},
}),
);

0 comments on commit ac41e73

Please sign in to comment.