fix(LevelMeterFab): replace MudFab with hand-rolled button+SVG so band color tinting is no longer overridden by MudBlazor internals

This commit is contained in:
daniel-c-harvey
2026-06-08 07:46:49 -04:00
parent 9169493d41
commit 7eae599490
4 changed files with 42 additions and 27 deletions
@@ -1,9 +1,7 @@
@if (_isMinimized)
{
<div class="minimized-dock">
<LevelMeterFab Size="Size.Large"
Color="Color.Primary"
OnClick="@ToggleMinimized" />
<LevelMeterFab OnClick="@ToggleMinimized" />
</div>
}
else
@@ -1,8 +1,7 @@
@namespace DeepDrftPublic.Client.Controls.AudioPlayerBar
<div class="lmf-root @_bandClass">
<MudFab Color="Color"
StartIcon="@Icons.Material.Filled.MusicNote"
Size="Size"
OnClick="OnClick"/>
</div>
<button class="lmf-fab-btn @_bandClass" type="button" @onclick="OnClick">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="lmf-icon" aria-hidden="true">
<path fill="currentColor" d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/>
</svg>
</button>
@@ -1,6 +1,5 @@
using DeepDrftPublic.Client.Services;
using Microsoft.AspNetCore.Components;
using MudBlazor;
namespace DeepDrftPublic.Client.Controls.AudioPlayerBar;
@@ -11,8 +10,6 @@ public partial class LevelMeterFab : ComponentBase, IAsyncDisposable
[CascadingParameter] public IStreamingPlayerService? PlayerService { get; set; }
[Parameter] public EventCallback OnClick { get; set; }
[Parameter] public Size Size { get; set; } = Size.Large;
[Parameter] public Color Color { get; set; } = Color.Primary;
// Level-data reduction tuning (see PLAN-level-meter-fab.md §2/§4). The three
// band boundaries below are the spec contract; the attack/release coefficients
@@ -1,27 +1,48 @@
/* Band color variables — tune here, applied everywhere below */
:root {
--lmf-green: #2ECC71;
--lmf-green: #2ECC71;
--lmf-yellow: #F4C430;
--lmf-orange: #FF6B35;
}
/* The wrapper div is the isolation anchor; MudFab wraps the glyph in its own
markup, so the band tint reaches the rendered SVG via :deep(). currentColor
on the idle (no-band) state inherits MudFab's Color.Primary contrast text. */
.lmf-root :deep(svg) {
transition: color 120ms ease-out;
/* Circular FAB matching MudFab Size.Large (56px) with MudBlazor primary palette */
.lmf-fab-btn {
width: 56px;
height: 56px;
border-radius: 50%;
border: none;
cursor: pointer;
background-color: var(--mud-palette-primary);
color: var(--mud-palette-primary-text);
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0px 3px 5px -1px rgba(0,0,0,.2),
0px 6px 10px 0px rgba(0,0,0,.14),
0px 1px 18px 0px rgba(0,0,0,.12);
transition: box-shadow 150ms ease-out;
padding: 0;
}
.lmf-green :deep(svg) {
color: var(--lmf-green);
filter: drop-shadow(0 0 6px rgba(46, 204, 113, 0.45));
.lmf-fab-btn:hover {
box-shadow: 0px 7px 8px -4px rgba(0,0,0,.2),
0px 12px 17px 2px rgba(0,0,0,.14),
0px 5px 22px 4px rgba(0,0,0,.12);
}
.lmf-yellow :deep(svg) {
color: var(--lmf-yellow);
filter: drop-shadow(0 0 6px rgba(244, 196, 48, 0.45));
.lmf-fab-btn:focus-visible {
outline: 2px solid var(--mud-palette-primary);
outline-offset: 3px;
}
.lmf-orange :deep(svg) {
color: var(--lmf-orange);
filter: drop-shadow(0 0 6px rgba(255, 107, 53, 0.45));
/* The icon SVG — transitions on both color and glow */
.lmf-icon {
width: 24px;
height: 24px;
transition: color 120ms ease-out, filter 120ms ease-out;
}
/* Band tints — applied directly to the SVG via fill="currentColor" */
.lmf-green .lmf-icon { color: var(--lmf-green); filter: drop-shadow(0 0 6px rgba(46, 204, 113, 0.45)); }
.lmf-yellow .lmf-icon { color: var(--lmf-yellow); filter: drop-shadow(0 0 6px rgba(244, 196, 48, 0.45)); }
.lmf-orange .lmf-icon { color: var(--lmf-orange); filter: drop-shadow(0 0 6px rgba(255, 107, 53, 0.45)); }