diff --git a/pkg/ui/v1beta1/frontend/src/app/services/theme.service.spec.ts b/pkg/ui/v1beta1/frontend/src/app/services/theme.service.spec.ts new file mode 100644 index 00000000000..e973a86bd54 --- /dev/null +++ b/pkg/ui/v1beta1/frontend/src/app/services/theme.service.spec.ts @@ -0,0 +1,22 @@ +import { TestBed } from '@angular/core/testing'; +import { ThemeService } from './theme.service'; + +describe('ThemeService', () => { + let service: ThemeService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(ThemeService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); + + it('should toggle theme and update localStorage', () => { + const initial = localStorage.getItem('katib-theme'); + service.toggle(); + const updated = localStorage.getItem('katib-theme'); + expect(updated).not.toBe(initial); + }); +}); diff --git a/pkg/ui/v1beta1/frontend/src/app/services/theme.service.ts b/pkg/ui/v1beta1/frontend/src/app/services/theme.service.ts new file mode 100644 index 00000000000..7fe47d9662c --- /dev/null +++ b/pkg/ui/v1beta1/frontend/src/app/services/theme.service.ts @@ -0,0 +1,30 @@ +import { Injectable } from '@angular/core'; +import { BehaviorSubject } from 'rxjs'; + +@Injectable({ providedIn: 'root' }) +export class ThemeService { + private isDark = new BehaviorSubject(this.getSavedTheme()); + isDark$ = this.isDark.asObservable(); + + private getSavedTheme(): boolean { + const saved = localStorage.getItem('katib-theme'); + if (saved) return saved === 'dark'; + return window.matchMedia('(prefers-color-scheme: dark)').matches; + } + + toggle(): void { + const newValue = !this.isDark.value; + this.isDark.next(newValue); + localStorage.setItem('katib-theme', newValue ? 'dark' : 'light'); + document.documentElement.setAttribute('data-theme', newValue ? 'dark' : 'light'); + document.body.classList.toggle('dark-theme', newValue); + document.body.classList.toggle('light-theme', !newValue); + } + + initTheme(): void { + const dark = this.getSavedTheme(); + document.documentElement.setAttribute('data-theme', dark ? 'dark' : 'light'); + document.body.classList.toggle('dark-theme', dark); + document.body.classList.toggle('light-theme', !dark); + } +}