Ui/DesignSystem/PlotterButton.razor

A reusable button UI component for the CitySim game. It defines the structure and behavior of a clickable button, including support for icons, text labels, visual variants, and event handling.

@namespace CitySim.DesignSystem
@using Sandbox.UI
@using CitySim.Punchboard
@inherits Panel

<root class="plotter-button @EffectiveVariant @Size.Css() @CssClass @(Toggled ? "toggled" : "") @(Disabled ? "disabled" : "") @(Focused ? "focused" : "")">
    <div class="plotter-button-content">
        @if ( !string.IsNullOrEmpty( Icon ) ) { <span>@Icon</span> }
        @if ( !string.IsNullOrEmpty( DisplayLabel ) ) { <span>@(GameText.Plain(DisplayLabel))</span> }
        @ChildContent
    </div>
</root>

@code
{
    [Parameter] public new RenderFragment ChildContent { get; set; }
    [Parameter] public string Label { get; set; }
    [Parameter] public string Text { get; set; }
    [Parameter] public string Icon { get; set; }
    [Parameter] public string CssClass { get; set; }
    [Parameter] public PbButtonKind? Kind { get; set; }
    [Parameter] public PbSize Size { get; set; } = PbSize.Normal;
    [Parameter] public bool Toggled { get; set; }
    string DisplayLabel => Label ?? Text;
    string EffectiveVariant => Kind switch { PbButtonKind.Secondary => "secondary", PbButtonKind.Tertiary => "tertiary", PbButtonKind.Ghost => "quiet", PbButtonKind.Danger => "danger", PbButtonKind.Primary => "primary", _ => Variant };
    /// <summary>primary, secondary, or quiet.</summary>
    [Parameter] public string Variant { get; set; } = "primary";
    [Parameter] public bool Disabled { get; set; }
    /// <summary>External focus marker for an owning navigation system; native focus is also styled.</summary>
    [Parameter] public bool Focused { get; set; }

    [Parameter] public string Help { get; set; }
    [Parameter] public Action Clicked { get; set; }

    protected override void OnParametersSet()
    {
        base.OnParametersSet();
        AcceptsFocus = !Disabled;
        Tooltip = Help;
        TooltipClass = "city-tooltip";
    }
    protected override void OnClick( MousePanelEvent e ) { base.OnClick( e ); Activate(); }
    public override void OnButtonEvent( ButtonEvent e )
    {
        base.OnButtonEvent( e );
        if ( HasFocus && e.Pressed && (e.Button == "enter" || e.Button == "space") ) Activate();
    }
    float lastActivation = -100;
    public void Activate()
    {
        if ( Disabled || lastActivation == Time.Now ) return;
        lastActivation = Time.Now;
        TabletopAudio.Click();
        Clicked?.Invoke();
    }
    protected override int BuildHash() => HashCode.Combine(GameText.LanguageCode, HashCode.Combine( Label, Text, Icon, CssClass, Kind, Size, Toggled, HashCode.Combine(Variant, Disabled, Focused, Help) ));
}