+
@if (ShowIconDiv())
{
diff --git a/src/Blazored.Toast/BlazoredToast.razor.cs b/src/Blazored.Toast/BlazoredToast.razor.cs
index 430be98..72016e6 100644
--- a/src/Blazored.Toast/BlazoredToast.razor.cs
+++ b/src/Blazored.Toast/BlazoredToast.razor.cs
@@ -1,6 +1,8 @@
using Blazored.Toast.Configuration;
using Blazored.Toast.Services;
using Microsoft.AspNetCore.Components;
+using Microsoft.AspNetCore.Components.Web;
+using System.Diagnostics;
namespace Blazored.Toast;
@@ -23,13 +25,13 @@ protected override async Task OnInitializedAsync()
{
if (Settings.ShowProgressBar)
{
- _countdownTimer = new CountdownTimer(Settings.Timeout)
+ _countdownTimer = new CountdownTimer(Settings.Timeout, Settings.ExtendedTimeout)
.OnTick(CalculateProgressAsync)
.OnElapsed(Close);
}
else
{
- _countdownTimer = new CountdownTimer(Settings.Timeout)
+ _countdownTimer = new CountdownTimer(Settings.Timeout, Settings.ExtendedTimeout)
.OnElapsed(Close);
}
@@ -42,6 +44,25 @@ protected override async Task OnInitializedAsync()
public void Close()
=> ToastsContainer.RemoveToast(ToastId);
+ private void MouseOver(MouseEventArgs e)
+ {
+ if (Settings.PauseProgressOnHover)
+ {
+ Settings.ShowProgressBar= false;
+ _countdownTimer?.Pause();
+ }
+ }
+
+ private void MouseOut()
+ {
+ if (Settings.PauseProgressOnHover )
+ {
+ Settings.ShowProgressBar = true;
+ _countdownTimer?.UnPause();
+ }
+ }
+
+
private async Task CalculateProgressAsync(int percentComplete)
{
_progress = 100 - percentComplete;
diff --git a/src/Blazored.Toast/BlazoredToast.razor.css b/src/Blazored.Toast/BlazoredToast.razor.css
index fb16846..701fd95 100644
--- a/src/Blazored.Toast/BlazoredToast.razor.css
+++ b/src/Blazored.Toast/BlazoredToast.razor.css
@@ -104,7 +104,7 @@
height: 6px;
border-bottom-left-radius: .375rem;
background-image: linear-gradient(rgba(0, 0, 0, 0.1) 0 0);
- transition: all .5s linear;
+ transition: all .1s linear;
}
.blazored-toast-action {
diff --git a/src/Blazored.Toast/BlazoredToasts.razor.cs b/src/Blazored.Toast/BlazoredToasts.razor.cs
index f9d025e..742e3dd 100644
--- a/src/Blazored.Toast/BlazoredToasts.razor.cs
+++ b/src/Blazored.Toast/BlazoredToasts.razor.cs
@@ -81,6 +81,9 @@ private ToastSettings BuildToastSettings(ToastLevel level, RenderFragment messag
ShowCloseButton,
toastInstanceSettings.OnClick,
Timeout),
+ toastInstanceSettings.Timeout == 0 ? Timeout : toastInstanceSettings.Timeout,
+ toastInstanceSettings.PauseProgressOnHover,
+ toastInstanceSettings.ExtendedTimeout),
ToastLevel.Info => new ToastSettings(
"blazored-toast-info",
toastInstanceSettings.IconType ?? IconType,
@@ -88,6 +91,9 @@ private ToastSettings BuildToastSettings(ToastLevel level, RenderFragment messag
ShowProgressBar,
ShowCloseButton,
toastInstanceSettings.OnClick,
+ toastInstanceSettings.Timeout == 0 ? Timeout : toastInstanceSettings.Timeout,
+ toastInstanceSettings.PauseProgressOnHover,
+ toastInstanceSettings.ExtendedTimeout),
Timeout),
ToastLevel.Success => new ToastSettings(
"blazored-toast-success",
@@ -96,6 +102,9 @@ private ToastSettings BuildToastSettings(ToastLevel level, RenderFragment messag
ShowProgressBar,
ShowCloseButton,
toastInstanceSettings.OnClick,
+ toastInstanceSettings.Timeout == 0 ? Timeout : toastInstanceSettings.Timeout,
+ toastInstanceSettings.PauseProgressOnHover,
+ toastInstanceSettings.ExtendedTimeout),
Timeout),
ToastLevel.Warning => new ToastSettings(
"blazored-toast-warning",
@@ -104,6 +113,9 @@ private ToastSettings BuildToastSettings(ToastLevel level, RenderFragment messag
ShowProgressBar,
ShowCloseButton,
toastInstanceSettings.OnClick,
+ toastInstanceSettings.Timeout == 0 ? Timeout : toastInstanceSettings.Timeout,
+ toastInstanceSettings.PauseProgressOnHover,
+ toastInstanceSettings.ExtendedTimeout),
Timeout),
_ => throw new InvalidOperationException()
};
diff --git a/src/Blazored.Toast/Configuration/ToastSettings.cs b/src/Blazored.Toast/Configuration/ToastSettings.cs
index 23de351..e20f9df 100644
--- a/src/Blazored.Toast/Configuration/ToastSettings.cs
+++ b/src/Blazored.Toast/Configuration/ToastSettings.cs
@@ -5,14 +5,46 @@ namespace Blazored.Toast.Configuration;
public class ToastSettings
{
+ ///
+ /// Add additional classes that will be applied to toast component
+ ///
public string AdditionalClasses { get; set; }
+ ///
+ /// Icon name, currently supporeted names for FontAwesome icons, Material icons
+ ///
public string? Icon { get; set; }
+ ///
+ ///
+ ///
public IconType? IconType { get; set; }
+ ///
+ /// When enabled progress will be shown until toaster is closed based on value
+ ///
public bool ShowProgressBar { get; set; }
+ ///
+ /// When enabled and mouse is over the toast, timeout period will be paused.
+ /// Use this with
+ ///
+ public bool PauseProgressOnHover { get; set; }
+ ///
+ ///
+ ///
public bool ShowCloseButton { get; set; }
+ ///
+ ///
+ ///
public Action? OnClick { get; set; }
+ ///
+ /// Timeout in seconds for toaster to close
+ ///
public int Timeout { get; set; }
-
+ ///
+ /// When is enabled, set ExtentedTimeout in seconds
+ /// to close toast after mouse loose focus.
+ /// Default value is 0, meaning no extended timeout
+ ///
+ public int ExtendedTimeout { get; set; }
+
public ToastSettings(
string additionalClasses,
IconType? iconType,
@@ -20,7 +52,9 @@ public ToastSettings(
bool showProgressBar,
bool showCloseButton,
Action? onClick,
- int timeout)
+ int timeout,
+ bool pauseProgressOnHover,
+ int extendedTimeout)
{
AdditionalClasses = additionalClasses;
IconType = iconType;
@@ -29,13 +63,16 @@ public ToastSettings(
ShowCloseButton = showCloseButton;
OnClick = onClick;
Timeout = timeout;
+ PauseProgressOnHover = pauseProgressOnHover;
+ ExtendedTimeout = extendedTimeout;
if (onClick is not null)
{
AdditionalClasses += " blazored-toast-action";
}
+ ExtendedTimeout = extendedTimeout;
}
-
+
#pragma warning disable CS8618
internal ToastSettings() { }
#pragma warning restore CS8618
diff --git a/src/Blazored.Toast/CountdownTimer.cs b/src/Blazored.Toast/CountdownTimer.cs
index 81ec3e3..5b6f948 100644
--- a/src/Blazored.Toast/CountdownTimer.cs
+++ b/src/Blazored.Toast/CountdownTimer.cs
@@ -1,57 +1,72 @@
-namespace Blazored.Toast;
+using System.Threading;
+namespace Blazored.Toast;
internal class CountdownTimer : IDisposable
{
- private readonly PeriodicTimer _timer;
+ private PeriodicTimer _timer;
private readonly int _ticksToTimeout;
private readonly CancellationToken _cancellationToken;
+ private readonly int _extendedTimeout;
private int _percentComplete;
-
+ private bool _isPaused;
private Func? _tickDelegate;
private Action? _elapsedDelegate;
-
- internal CountdownTimer(int timeout, CancellationToken cancellationToken = default)
+ internal CountdownTimer(int timeout, int extendedTimeout = 0, CancellationToken cancellationToken = default)
{
_ticksToTimeout = 100;
_timer = new PeriodicTimer(TimeSpan.FromMilliseconds(timeout * 10));
_cancellationToken = cancellationToken;
+ _extendedTimeout = extendedTimeout;
}
-
internal CountdownTimer OnTick(Func updateProgressDelegate)
{
_tickDelegate = updateProgressDelegate;
return this;
}
-
internal CountdownTimer OnElapsed(Action elapsedDelegate)
{
_elapsedDelegate = elapsedDelegate;
return this;
}
-
internal async Task StartAsync()
{
_percentComplete = 0;
await DoWorkAsync();
}
-
+ internal void Pause()
+ {
+ _isPaused = true;
+ }
+ internal async Task UnPause()
+ {
+ _isPaused = false;
+ if (_extendedTimeout > 0)
+ {
+ _timer?.Dispose();
+ _timer = new PeriodicTimer(TimeSpan.FromMilliseconds(_extendedTimeout * 10));
+ await StartAsync();
+ }
+ }
private async Task DoWorkAsync()
{
while (await _timer.WaitForNextTickAsync(_cancellationToken) && !_cancellationToken.IsCancellationRequested)
{
- _percentComplete++;
+
+ if (!_isPaused)
+ {
+ _percentComplete++;
+ }
if (_tickDelegate != null)
{
await _tickDelegate(_percentComplete);
}
//await _tickDelegate?.Invoke(_percentComplete)!;
-
+
if (_percentComplete == _ticksToTimeout)
{
_elapsedDelegate?.Invoke();
}
}
}
-
public void Dispose() => _timer.Dispose();
}