Files
EnvelopeGenerator/EnvelopeGenerator.Server/EnvelopeGenerator.Server.Client/Layout/ThemeControls.razor

96 lines
3.2 KiB
Plaintext

@using EnvelopeGenerator.Server.Client.Services
@rendermode InteractiveWebAssembly
@implements IDisposable
@inject ThemeService ThemeService
<div class="sf-theme-slider">
@* Moon — left end (blazing-dark) *@
<svg class="sf-theme-icon @(ThemeService.ThemeName == "blazing-dark" ? "sf-theme-icon--active" : "")"
xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" viewBox="0 0 24 24"
title="Blazing Dark">
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>
</svg>
@* Track wrapper: range input + left/mid/right ticks *@
<div class="sf-theme-track-wrapper">
@* Left tick *@
<div class="sf-theme-tick sf-theme-tick--left"></div>
@* Mid tick (marks the middle position) *@
<div class="sf-theme-tick sf-theme-tick--mid"></div>
@* Right tick *@
<div class="sf-theme-tick sf-theme-tick--right"></div>
<input type="range"
class="sf-theme-range"
min="0" max="2" step="1"
value="@SliderValue"
@oninput="OnSliderChanged"
title="@ThemeService.AvailableThemes[SliderValue].Label" />
</div>
@* Sun — right end (purple) *@
<svg class="sf-theme-icon @(ThemeService.ThemeName == "purple" ? "sf-theme-icon--active" : (ThemeService.ThemeName == "blazing-berry" ? "sf-theme-icon--mid" : ""))"
xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" viewBox="0 0 24 24"
stroke="currentColor" stroke-width="1.5"
title="Blazing Berry / Purple">
<circle cx="12" cy="12" r="4" fill="currentColor" stroke="none"/>
<line x1="12" y1="2" x2="12" y2="5"/>
<line x1="12" y1="19" x2="12" y2="22"/>
<line x1="4.22" y1="4.22" x2="6.34" y2="6.34"/>
<line x1="17.66" y1="17.66" x2="19.78" y2="19.78"/>
<line x1="2" y1="12" x2="5" y2="12"/>
<line x1="19" y1="12" x2="22" y2="12"/>
<line x1="4.22" y1="19.78" x2="6.34" y2="17.66"/>
<line x1="17.66" y1="6.34" x2="19.78" y2="4.22"/>
</svg>
</div>
@code {
private Action? _themeChangeHandler;
/// <summary>
/// Maps the active theme to a 0-based slider step.
/// 0 = blazing-dark (🌙 left)
/// 1 = blazing-berry (middle)
/// 2 = purple (☀️ right)
/// </summary>
private int SliderValue => ThemeService.ThemeName switch
{
"blazing-dark" => 0,
"purple" => 2,
_ => 1
};
protected override void OnInitialized()
{
_themeChangeHandler = () => InvokeAsync(StateHasChanged);
ThemeService.OnChange += _themeChangeHandler;
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
await ThemeService.InitializeAsync();
}
private async Task OnSliderChanged(ChangeEventArgs e)
{
if (!int.TryParse(e.Value?.ToString(), out var step)) return;
var themeName = step switch
{
0 => "blazing-dark",
2 => "purple",
_ => "blazing-berry"
};
await ThemeService.SetThemeAsync(themeName);
}
public void Dispose()
=> ThemeService.OnChange -= _themeChangeHandler;
}