feat: update theme preference handling in ThemeService and index.html
This commit is contained in:
1 parent
c8020c489e
commit
45de0cebcc
3 files changed
+44
-15
No files matched your search
@@ -3,9 +3,26 @@ import { vi } from 'vitest';
|
|||||||
import { ThemeService } from './theme.service';
|
import { ThemeService } from './theme.service';
|
||||||
|
|
||||||
describe('ThemeService', () => {
|
describe('ThemeService', () => {
|
||||||
|
beforeEach(() => localStorage.clear());
|
||||||
|
|
||||||
|
it('defaults to the operating-system preference', () => {
|
||||||
|
vi.stubGlobal(
|
||||||
|
'matchMedia',
|
||||||
|
vi.fn(() => ({ matches: true, addEventListener: vi.fn() })),
|
||||||
|
);
|
||||||
|
const service = TestBed.inject(ThemeService);
|
||||||
|
TestBed.tick();
|
||||||
|
|
||||||
|
expect(service.preference()).toBe('system');
|
||||||
|
expect(document.documentElement.dataset['theme']).toBe('dark');
|
||||||
|
});
|
||||||
|
|
||||||
it('persists explicit and system preferences', () => {
|
it('persists explicit and system preferences', () => {
|
||||||
const listener = vi.fn();
|
const listener = vi.fn();
|
||||||
vi.stubGlobal('matchMedia', vi.fn(() => ({ matches: true, addEventListener: listener })));
|
vi.stubGlobal(
|
||||||
|
'matchMedia',
|
||||||
|
vi.fn(() => ({ matches: true, addEventListener: listener })),
|
||||||
|
);
|
||||||
localStorage.setItem('lmnp-theme', 'system');
|
localStorage.setItem('lmnp-theme', 'system');
|
||||||
const service = TestBed.inject(ThemeService);
|
const service = TestBed.inject(ThemeService);
|
||||||
TestBed.tick();
|
TestBed.tick();
|
||||||
|
|||||||
@@ -40,6 +40,6 @@ export class ThemeService {
|
|||||||
const storedPreference = localStorage.getItem(THEME_STORAGE_KEY);
|
const storedPreference = localStorage.getItem(THEME_STORAGE_KEY);
|
||||||
return storedPreference === 'dark' || storedPreference === 'system'
|
return storedPreference === 'dark' || storedPreference === 'system'
|
||||||
? storedPreference
|
? storedPreference
|
||||||
: 'light';
|
: 'system';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+25
-13
@@ -1,16 +1,28 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>LmnpFrontend</title>
|
||||||
|
<base href="/" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<script>
|
||||||
|
try {
|
||||||
|
const preference = localStorage.getItem('lmnp-theme');
|
||||||
|
const theme =
|
||||||
|
preference === 'light' || preference === 'dark'
|
||||||
|
? preference
|
||||||
|
: matchMedia('(prefers-color-scheme: dark)').matches
|
||||||
|
? 'dark'
|
||||||
|
: 'light';
|
||||||
|
document.documentElement.dataset.theme = theme;
|
||||||
|
document.documentElement.dataset.themePreference =
|
||||||
|
preference === 'light' || preference === 'dark' ? preference : 'system';
|
||||||
|
} catch {}
|
||||||
|
</script>
|
||||||
|
<link rel="icon" type="image/x-icon" href="favicon.ico" />
|
||||||
|
</head>
|
||||||
|
|
||||||
<head>
|
<body>
|
||||||
<meta charset="utf-8">
|
<app-root></app-root>
|
||||||
<title>LmnpFrontend</title>
|
</body>
|
||||||
<base href="/">
|
</html>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<app-root></app-root>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
Reference in new issue
Block a user