A Blazor-like/sandbox UI component for a toast notification. Renders title, message, optional icon and copy button, computes a tone CSS class, supports dismiss and clipboard copy with callbacks.
@namespace Sunless.Libraries.UI
@using Sandbox
@using Sandbox.UI
@attribute [StyleSheet]
@inherits Panel
<root>
@if ( !string.IsNullOrEmpty( Message ) )
{
<div class="toast toast-@ToneClass">
@if ( !string.IsNullOrEmpty( Icon ) )
{
<Icon Name=@Icon Size=@(IconSize.Large) ExtraClass="toast-icon" />
}
<div class="toast-body" @onclick=@(() => OnDismiss?.Invoke())>
@if ( !string.IsNullOrEmpty( Title ) )
{
<div class="toast-title">@Title</div>
}
<div class="toast-message">@Message</div>
</div>
@if ( ShowCopy )
{
<div class="toast-copy" @onclick=@CopyValueToClipboard>
<Icon Name="content_copy" Size=@(IconSize.Medium) />
</div>
}
</div>
}
</root>
@code
{
public string Title { get; set; } = "";
public string Message { get; set; }
public string Icon { get; set; }
public ToastTone Tone { get; set; } = ToastTone.Default;
public Action OnDismiss { get; set; }
public bool ShowCopy { get; set; }
public string CopyValue { get; set; }
public Action OnCopied { get; set; }
public Action OnCopyFailed { get; set; }
string ToneClass => Tone switch
{
ToastTone.Ok => "ok",
ToastTone.Warn => "warn",
ToastTone.Danger => "danger",
ToastTone.Info => "info",
_ => "default",
};
void CopyValueToClipboard()
{
var s = string.IsNullOrEmpty( CopyValue ) ? Message : CopyValue;
if ( string.IsNullOrEmpty( s ) ) return;
try
{
Sandbox.UI.Clipboard.SetText( s );
OnCopied?.Invoke();
}
catch ( Exception e )
{
Log.Warning( $"[Toast] clipboard copy failed: {e.Message}" );
OnCopyFailed?.Invoke();
}
}
protected override int BuildHash() => HashCode.Combine( Title, Message, Icon, Tone, ShowCopy, CopyValue );
}