Skip to content

Commit 52b69bb

Browse files
authored
feat(components): add ToastProvider component (#270)
* deps(components): add Blazor.Sonner package * feat(toast): setup Blazor Sonner for distribution * feat(theme): add `ThemeChanged` event and slightly improve API * feat(toast): add new `LumexToastProvider` component based on Blazor Sonner * docs(toast): add page with demos * docs(header): update star counter
1 parent 82200ef commit 52b69bb

File tree

29 files changed

+1314
-68
lines changed

29 files changed

+1314
-68
lines changed

LumexUI.sln

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
3-
# Visual Studio Version 17
4-
VisualStudioVersion = 17.2.32526.322
3+
# Visual Studio Version 18
4+
VisualStudioVersion = 18.2.11415.280 d18.0
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LumexUI", "src\LumexUI\LumexUI.csproj", "{F5DCF265-756B-4B25-AECA-15B9FF2DCB66}"
77
EndProject

docs/LumexUI.Docs.Client/Common/Navigation/NavigationStore.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ public class NavigationStore
4949
.Add( new( nameof( LumexSwitch ) ) )
5050
.Add( new( nameof( LumexTabs ) ) )
5151
.Add( new( nameof( LumexTextbox ) ) )
52+
.Add( new( nameof( LumexToastProvider ), PageStatus.New ) )
5253
.Add( new( nameof( LumexTooltip ) ) )
5354
.Add( new( nameof( LumexUser ), PageStatus.New ) );
5455

@@ -108,6 +109,7 @@ public class NavigationStore
108109
.Add( new( nameof( LumexTab ) ) )
109110
.Add( new( nameof( LumexTabs ) ) )
110111
.Add( new( nameof( LumexTextbox ) ) )
112+
.Add( new( nameof( LumexToastProvider ) ) )
111113
.Add( new( nameof( LumexThemeProvider ) ) )
112114
.Add( new( nameof( LumexTooltip ) ) )
113115
.Add( new( nameof( LumexUser ) ) );

docs/LumexUI.Docs.Client/Components/Header.razor

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
External="@true"
5757
Class="text-foreground-500 hover:text-foreground-600 hover:opacity-100">
5858
<GithubIcon Size="20" />
59-
<span class="ml-1.5 text-small font-medium">428</span>
59+
<span class="ml-1.5 text-small font-medium">448</span>
6060
</LumexLink>
6161
</LumexNavbarItem>
6262
</text>;

docs/LumexUI.Docs.Client/Components/Layouts/MainLayout.razor

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
@inherits LayoutComponentBase
33
@attribute [StreamRendering]
44

5+
<LumexToastProvider @rendermode="@InteractiveWebAssembly" />
6+
57
@Body
68

79
<div id="blazor-error-ui">
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
@using Blazor.Sonner.Services
2+
3+
@inject ToastService Toast
4+
5+
<div class="fixed z-100">
6+
<LumexToastProvider Id="toaster-close-button" CloseButton="@_closeButtonEnabled" />
7+
</div>
8+
9+
<div class="flex flex-wrap gap-2">
10+
<LumexButton Variant="@Variant.Flat" OnClick="@(() => ShowToast( enabled: false ))">
11+
Default
12+
</LumexButton>
13+
<LumexButton Variant="@Variant.Flat" OnClick="@(() => ShowToast( enabled: true ))">
14+
Close Button
15+
</LumexButton>
16+
</div>
17+
18+
@code {
19+
private bool _closeButtonEnabled;
20+
21+
private void ShowToast( bool enabled )
22+
{
23+
_closeButtonEnabled = enabled;
24+
25+
Toast.Show( "Event has been created", t =>
26+
{
27+
t.ToasterId = "toaster-close-button";
28+
t.Description = "Monday, January 3rd at 6:00pm";
29+
} );
30+
}
31+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
@using Blazor.Sonner.Services
2+
3+
@inject ToastService Toast
4+
5+
<div class="fixed z-100">
6+
<LumexToastProvider Id="toaster-expanded" Expand="@_toasterExpanded" />
7+
</div>
8+
9+
<div class="flex flex-wrap gap-2">
10+
<LumexButton Variant="@Variant.Flat" OnClick="@(() => ShowToast( expanded: false ))">
11+
Default
12+
</LumexButton>
13+
<LumexButton Variant="@Variant.Flat" OnClick="@(() => ShowToast( expanded: true ))">
14+
Expanded
15+
</LumexButton>
16+
</div>
17+
18+
@code {
19+
private bool _toasterExpanded;
20+
21+
private void ShowToast( bool expanded )
22+
{
23+
_toasterExpanded = expanded;
24+
25+
Toast.Show( "Event has been created", t =>
26+
{
27+
t.ToasterId = "toaster-expanded";
28+
t.Description = "Monday, January 3rd at 6:00pm";
29+
} );
30+
}
31+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
@using Blazor.Sonner.Services
2+
3+
@inject ToastService Toast
4+
5+
<div class="fixed z-100">
6+
<LumexToastProvider Id="toaster-other"
7+
Gap="@_gap"
8+
Duration="@TimeSpan.FromMilliseconds( _duration )"
9+
VisibleToasts="@_visibleToasts" />
10+
</div>
11+
12+
<div class="w-full grid items-center justify-items-center gap-4 md:grid-cols-2">
13+
<div>
14+
<LumexButton Variant="@Variant.Flat"
15+
OnClick="@(() => Toast.Show( "Event has been created", _toasterId ))">
16+
Show toast
17+
</LumexButton>
18+
</div>
19+
20+
<div class="flex flex-col gap-4">
21+
<LumexNumbox Label="Gap" LabelPlacement="@LabelPlacement.Outside" step="2" @bind-Value="@_gap" />
22+
<LumexNumbox Label="Duration" LabelPlacement="@LabelPlacement.Outside" step="500" @bind-Value="@_duration" />
23+
<LumexNumbox Label="Visible toasts" LabelPlacement="@LabelPlacement.Outside" @bind-Value="@_visibleToasts" />
24+
</div>
25+
</div>
26+
27+
@code {
28+
private Action<ToastModel> _toasterId = t => t.ToasterId = "toaster-other";
29+
30+
private int _gap = 14;
31+
private int _visibleToasts = 3;
32+
private double _duration = 4000;
33+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
@using Blazor.Sonner.Services
2+
@using System.Text.RegularExpressions
3+
4+
@inject ToastService Toast
5+
6+
<div class="fixed z-100">
7+
<LumexToastProvider Id="toaster-position" Position="@_selectedPosition" />
8+
</div>
9+
10+
<div class="flex flex-wrap gap-2">
11+
@foreach( var position in _positions )
12+
{
13+
<LumexButton Variant="@Variant.Flat" OnClick="@(() => ShowToast( position ))">
14+
@Regex.Replace( position.ToString(), "(?<!^)(?=[A-Z])", " " )
15+
</LumexButton>
16+
}
17+
</div>
18+
19+
@code {
20+
private ToastPosition _selectedPosition = ToastPosition.BottomRight;
21+
22+
private ToastPosition[] _positions = [
23+
ToastPosition.TopLeft,
24+
ToastPosition.TopCenter,
25+
ToastPosition.TopRight,
26+
ToastPosition.BottomLeft,
27+
ToastPosition.BottomCenter,
28+
ToastPosition.BottomRight
29+
];
30+
31+
private void ShowToast( ToastPosition position )
32+
{
33+
_selectedPosition = position;
34+
35+
Toast.Show( "Event has been created", t =>
36+
{
37+
t.ToasterId = "toaster-position";
38+
t.Description = "Monday, January 3rd at 6:00pm";
39+
} );
40+
}
41+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
@using Blazor.Sonner.Services
2+
3+
@inject ToastService Toast
4+
5+
<div class="fixed z-100">
6+
<LumexToastProvider Id="toaster-rich-colors" RichColors="@true" />
7+
</div>
8+
9+
<div class="flex flex-wrap gap-2">
10+
<LumexButton Variant="@Variant.Flat"
11+
Color="@ThemeColor.Info"
12+
OnClick="@(() => Toast.Info( "Be at the area 10 minutes before the event time", _toasterId ))">
13+
Info
14+
</LumexButton>
15+
16+
<LumexButton Variant="@Variant.Flat"
17+
Color="@ThemeColor.Success"
18+
OnClick="@(() => Toast.Success( "Event has been created", _toasterId ))">
19+
Success
20+
</LumexButton>
21+
22+
<LumexButton Variant="@Variant.Flat"
23+
Color="@ThemeColor.Warning"
24+
OnClick="@(() => Toast.Warning( "Event start time cannot be earlier than 8am", _toasterId ))">
25+
Warning
26+
</LumexButton>
27+
28+
<LumexButton Variant="@Variant.Flat"
29+
Color="@ThemeColor.Danger"
30+
OnClick="@(() => Toast.Error( "Event has not been created", _toasterId ))">
31+
Error
32+
</LumexButton>
33+
</div>
34+
35+
@code {
36+
private Action<ToastModel> _toasterId = t => t.ToasterId = "toaster-rich-colors";
37+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
@using Blazor.Sonner.Services
2+
3+
@inject ToastService Toast
4+
5+
<div class="flex flex-wrap gap-2">
6+
<LumexButton Variant="@Variant.Flat" OnClick="@ShowDefaultToast">Default</LumexButton>
7+
<LumexButton Variant="@Variant.Flat" OnClick="@ShowDescriptionToast">Description</LumexButton>
8+
<LumexButton Variant="@Variant.Flat" OnClick="@ShowInfoToast">Info</LumexButton>
9+
<LumexButton Variant="@Variant.Flat" OnClick="@ShowSuccessToast">Success</LumexButton>
10+
<LumexButton Variant="@Variant.Flat" OnClick="@ShowWarningToast">Warning</LumexButton>
11+
<LumexButton Variant="@Variant.Flat" OnClick="@ShowErrorToast">Error</LumexButton>
12+
<LumexButton Variant="@Variant.Flat" OnClick="@ShowAsyncToast">Async</LumexButton>
13+
</div>
14+
15+
@code {
16+
private void ShowDefaultToast() => Toast.Show( "Event has been created" );
17+
private void ShowDescriptionToast()
18+
{
19+
Toast.Show( "Event has been created", t =>
20+
{
21+
t.Description = "Monday, January 3rd at 6:00pm";
22+
} );
23+
}
24+
private void ShowInfoToast() => Toast.Info( "Be at the area 10 minutes before the event time" );
25+
private void ShowSuccessToast() => Toast.Success( "Event has been created" );
26+
private void ShowWarningToast() => Toast.Warning( "Event start time cannot be earlier than 8am" );
27+
private void ShowErrorToast() => Toast.Error( "Event has not been created" );
28+
private void ShowAsyncToast()
29+
{
30+
Toast.Async( DoAsync(), t =>
31+
{
32+
t.Loading = "Loading...";
33+
t.Success = ( data ) => $"{data} toast has been added";
34+
t.Error = ( ex ) => ex.Message;
35+
} );
36+
37+
async Task<string> DoAsync()
38+
{
39+
// Simulate an async operation
40+
await Task.Delay( 2000 );
41+
return "Blazor Sonner";
42+
}
43+
}
44+
}

0 commit comments

Comments
 (0)