|
1 | 1 | @inject IJSRuntime JS |
| 2 | +@inject ThemeState Theme |
| 3 | +@implements IDisposable |
2 | 4 |
|
3 | | -<button type="button" class="theme-toggle" @onclick="Toggle" aria-label="Toggle theme"> |
4 | | - @if (_isDark) |
| 5 | +<button type="button" class="theme-toggle" @onclick="OnClick" aria-label="Toggle theme"> |
| 6 | + @if (Theme.IsDark) |
5 | 7 | { |
6 | | - <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41"/></svg> |
| 8 | + <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg> |
7 | 9 | } |
8 | 10 | else |
9 | 11 | { |
10 | | - <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg> |
| 12 | + <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41"/></svg> |
11 | 13 | } |
12 | 14 | </button> |
13 | 15 |
|
14 | 16 | @code { |
15 | | - private bool _isDark; |
| 17 | + protected override void OnInitialized() => Theme.OnChange += StateHasChanged; |
16 | 18 |
|
17 | 19 | protected override async Task OnAfterRenderAsync(bool firstRender) |
18 | 20 | { |
19 | | - if (!firstRender) return; |
| 21 | + if (!firstRender || Theme.IsInitialized) return; |
20 | 22 | try |
21 | 23 | { |
22 | | - var current = await JS.InvokeAsync<string>("eval", "document.documentElement.classList.contains('dark') ? 'dark' : 'light'"); |
23 | | - _isDark = current == "dark"; |
24 | | - StateHasChanged(); |
| 24 | + var current = await JS.InvokeAsync<string>("eval", |
| 25 | + "document.documentElement.classList.contains('dark') ? 'dark' : 'light'"); |
| 26 | + Theme.Init(current == "dark"); |
25 | 27 | } |
26 | 28 | catch { } |
27 | 29 | } |
28 | 30 |
|
29 | | - private async Task Toggle() |
| 31 | + private async Task OnClick() |
30 | 32 | { |
31 | | - _isDark = !_isDark; |
| 33 | + Theme.Toggle(); |
32 | 34 | try |
33 | 35 | { |
34 | | - await JS.InvokeVoidAsync("eval", _isDark |
| 36 | + await JS.InvokeVoidAsync("eval", Theme.IsDark |
35 | 37 | ? "document.documentElement.classList.add('dark'); try { localStorage.setItem('shelldocs-theme','dark'); } catch{}" |
36 | 38 | : "document.documentElement.classList.remove('dark'); try { localStorage.setItem('shelldocs-theme','light'); } catch{}"); |
37 | 39 | } |
38 | 40 | catch { } |
39 | 41 | } |
| 42 | + |
| 43 | + public void Dispose() => Theme.OnChange -= StateHasChanged; |
40 | 44 | } |
0 commit comments