Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Added ability to display progress bar on toasts #65

Merged
merged 1 commit into from
May 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,18 @@ To show a toast just click one of the buttons below.
```
Full examples for client and server-side Blazor are included in the [samples](https://github.com/Blazored/Toast/tree/master/samples).

### Show Progress Bar
You can display a progress bar which gives a visual indicator of the time remaining before the toast will disappear. In order to show the progress bar set the `ShowProgressBar` parameter to true.

```html
<BlazoredToasts Position="ToastPosition.BottomRight"
Timeout="10"
ShowProgressBar="true" />
```

### Remove Toasts When Navigating
If you wish to clear any visible toasts when the user navigates to a new page you can enable the `RemoveToastsOnNavigation` parameter. Setting this to true will remove any visible toasts whenever the `LocationChanged` event fires.

## FAQ
### The toasts are not showing
- Check the `z-index` of your other `DOM Elements`, make sure that the `.blazored-toast-container` has a higher `z-index` than the other components.
Expand Down
3 changes: 2 additions & 1 deletion samples/BlazorServer/Shared/MainLayout.razor
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
ErrorIcon="error_outline"
InfoIcon="school"
SuccessIcon="done_outline"
WarningIcon="warning" />
WarningIcon="warning"
ShowProgressBar="@true"/>

<div class="sidebar">
<NavMenu />
Expand Down
9 changes: 8 additions & 1 deletion src/Blazored.Toast/BlazoredToast.razor
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@using Microsoft.AspNetCore.Components.Web

<div class="blazored-toast @ToastSettings.BaseClass @ToastSettings.AdditionalClasses">

@if (!string.IsNullOrWhiteSpace(ToastSettings.Icon))
{
<div class="blazored-toast-icon">
Expand Down Expand Up @@ -30,4 +30,11 @@
</div>
<p class="blazored-toast-message">@ToastSettings.Message</p>
</div>

@if (ToastSettings.ShowProgressBar)
{
<div class="blazored-toast-progressbar">
<span style="width: @(_progress)%;"></span>
</div>
}
</div>
23 changes: 15 additions & 8 deletions src/Blazored.Toast/BlazoredToast.razor.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Blazored.Toast.Configuration;
using Microsoft.AspNetCore.Components;
using System;
using System.Timers;
using System.Threading.Tasks;

namespace Blazored.Toast
{
Expand All @@ -13,14 +13,21 @@ public partial class BlazoredToast : IDisposable
[Parameter] public ToastSettings ToastSettings { get; set; }
[Parameter] public int Timeout { get; set; }

private Timer _timer;
private CountdownTimer _countdownTimer;
private int _progress = 100;

protected override void OnInitialized()
{
_timer = new Timer(Timeout * 1000);
_timer.Elapsed += (sender, args) => { Close(); };
_timer.AutoReset = false;
_timer.Start();
_countdownTimer = new CountdownTimer(Timeout);
_countdownTimer.OnTick += CalculateProgress;
_countdownTimer.OnElapsed += () => { Close(); };
_countdownTimer.Start();
}

private async void CalculateProgress(int percentComplete)
{
_progress = 100 - percentComplete;
await InvokeAsync(StateHasChanged);
}

private void Close()
Expand All @@ -30,8 +37,8 @@ private void Close()

public void Dispose()
{
_timer.Dispose();
_timer = null;
_countdownTimer.Dispose();
_countdownTimer = null;
}
}
}
9 changes: 5 additions & 4 deletions src/Blazored.Toast/BlazoredToasts.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public partial class BlazoredToasts
[Parameter] public ToastPosition Position { get; set; } = ToastPosition.TopRight;
[Parameter] public int Timeout { get; set; } = 5;
[Parameter] public bool RemoveToastsOnNavigation { get; set; }
[Parameter] public bool ShowProgressBar { get; set; }

private string PositionClass { get; set; } = string.Empty;
internal List<ToastInstance> ToastList { get; set; } = new List<ToastInstance>();
Expand Down Expand Up @@ -77,16 +78,16 @@ private ToastSettings BuildToastSettings(ToastLevel level, RenderFragment messag
switch (level)
{
case ToastLevel.Error:
return new ToastSettings(string.IsNullOrWhiteSpace(heading) ? "Error" : heading, message, IconType, "blazored-toast-error", ErrorClass, ErrorIcon);
return new ToastSettings(string.IsNullOrWhiteSpace(heading) ? "Error" : heading, message, IconType, "blazored-toast-error", ErrorClass, ErrorIcon, ShowProgressBar);

case ToastLevel.Info:
return new ToastSettings(string.IsNullOrWhiteSpace(heading) ? "Info" : heading, message, IconType, "blazored-toast-info", InfoClass, InfoIcon);
return new ToastSettings(string.IsNullOrWhiteSpace(heading) ? "Info" : heading, message, IconType, "blazored-toast-info", InfoClass, InfoIcon, ShowProgressBar);

case ToastLevel.Success:
return new ToastSettings(string.IsNullOrWhiteSpace(heading) ? "Success" : heading, message, IconType, "blazored-toast-success", SuccessClass, SuccessIcon);
return new ToastSettings(string.IsNullOrWhiteSpace(heading) ? "Success" : heading, message, IconType, "blazored-toast-success", SuccessClass, SuccessIcon, ShowProgressBar);

case ToastLevel.Warning:
return new ToastSettings(string.IsNullOrWhiteSpace(heading) ? "Warning" : heading, message, IconType, "blazored-toast-warning", WarningClass, WarningIcon);
return new ToastSettings(string.IsNullOrWhiteSpace(heading) ? "Warning" : heading, message, IconType, "blazored-toast-warning", WarningClass, WarningIcon, ShowProgressBar);
}

throw new InvalidOperationException();
Expand Down
5 changes: 4 additions & 1 deletion src/Blazored.Toast/Configuration/ToastSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@ public ToastSettings(
IconType? iconType,
string baseClass,
string additionalClasses,
string icon)
string icon,
bool showProgressBar)
{
Heading = heading;
Message = message;
IconType = iconType;
BaseClass = baseClass;
AdditionalClasses = additionalClasses;
Icon = icon;
ShowProgressBar = showProgressBar;
}

public string Heading { get; set; }
Expand All @@ -26,5 +28,6 @@ public ToastSettings(
public string AdditionalClasses { get; set; }
public string Icon { get; set; }
public IconType? IconType { get; set; }
public bool ShowProgressBar { get; set; }
}
}
60 changes: 60 additions & 0 deletions src/Blazored.Toast/CountdownTimer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using System;
using System.Threading.Tasks;
using System.Timers;
using Microsoft.AspNetCore.Components;

namespace Blazored.Toast
{
internal class CountdownTimer : IDisposable
{
private Timer _timer;
private int _timeout;
private int _countdownTotal;
private int _percentComplete;

internal Action<int> OnTick;
internal Action OnElapsed;

internal CountdownTimer(int timeout)
{
_countdownTotal = timeout;
_timeout = (_countdownTotal * 1000) / 100;
_percentComplete = 0;
SetupTimer();
}

internal void Start()
{
_timer.Start();
}

private void SetupTimer()
{
_timer = new Timer(_timeout);
_timer.Elapsed += HandleTick;
_timer.AutoReset = false;
}

private void HandleTick(object sender, ElapsedEventArgs args)
{
_percentComplete++;
OnTick?.Invoke(_percentComplete);

if (_percentComplete == 100)
{
OnElapsed?.Invoke();
}
else
{
SetupTimer();
Start();
}
}

public void Dispose()
{
_timer.Dispose();
_timer = null;
}
}
}
37 changes: 36 additions & 1 deletion src/Blazored.Toast/wwwroot/blazored-toast.css
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

.blazored-toast {
display: flex;
position: relative;
flex-direction: row;
animation: fadein 1.5s;
margin-bottom: 1rem;
Expand Down Expand Up @@ -76,14 +77,48 @@
background-color: transparent;
border: 0;
-webkit-appearance: none;
color:inherit;
color: inherit;
font-size: 1.25rem;
}

.blazored-toast-body p {
margin-bottom: 0;
font-size: 1rem;
}

.blazored-toast-progressbar {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 8px;
border-bottom-left-radius: .25rem;
border-bottom-right-radius: .25rem;
}

.blazored-toast-info .blazored-toast-progressbar > span {
background-color: #34a9ad;
}

.blazored-toast-success .blazored-toast-progressbar > span {
background-color: #5fba7d;
}

.blazored-toast-warning .blazored-toast-progressbar > span {
background-color: #c1c13e;
}

.blazored-toast-error .blazored-toast-progressbar > span {
background-color: #ba5e5e;
}

.blazored-toast-progressbar > span {
position: absolute;
filter: brightness(75%);
height: 8px;
border-bottom-left-radius: .25rem;
}

@keyframes fadein {
from {
opacity: 0;
Expand Down