Skip to content
Open
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
18 changes: 15 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

Blazor toast notifications shell using Tailwindcss v2.0+

> **Requires .NET 9.0 or later.**

Thank you to Chris Sanity for the base functionality through Blazored.Toasts. This is basically a fork of his work.

This version uses Tailwindcss instead of bootstrap. There are a few base styles included, however, With TailBlazor being so incredibly low level there is the option to load entire render fragments in instead to give unlimited customization to toasts
Expand Down Expand Up @@ -50,7 +52,17 @@ Add this to the top of your MainLayout.razor component.

`<TailBlazorToasts />`

### 4. Using basic components
### 4. Enable interactive rendering

TailBlazor.Toast is ready for Blazor's interactive *Auto* render mode. When the component is rendered it automatically lights up on the client regardless of whether the host app is prerendering for WebAssembly, Server, or switching between them at runtime. For standalone pages or layouts you can optionally opt into Auto mode explicitly by adding the following directive:

```
@rendermode InteractiveAuto
```

The included sample app shows this directive in `App.razor` for reference.

### 5. Using basic components

Edit the TailBlazorToasts component in mainlayout with your base settings

Expand All @@ -77,7 +89,7 @@ Edit the TailBlazorToasts component in mainlayout with your base settings
```


#### 5. Create your custom toast component
#### 6. Create your custom toast component

You can create the template that you'll use for some or all of your toasts using tailwind.

Expand Down Expand Up @@ -112,7 +124,7 @@ Here is a basic example. Create a folder named `Toasts` and create a component c
</div>
```

#### 5. Use your toast component
#### 6. Use your toast component

Go to Index and inject your toast service

Expand Down
23 changes: 13 additions & 10 deletions samples/TailBlazor.ToastServer/App.razor
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
<Router AppAssembly="@typeof(Program).Assembly" PreferExactMatches="@true">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
</Found>
<NotFound>
<LayoutView Layout="@typeof(MainLayout)">
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
@using Microsoft.AspNetCore.Components.Web
@rendermode InteractiveAuto

<Router AppAssembly="@typeof(Program).Assembly" PreferExactMatches="@true">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
</Found>
<NotFound>
<LayoutView Layout="@typeof(MainLayout)">
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
2 changes: 1 addition & 1 deletion samples/TailBlazor.ToastServer/Shared/MainLayout.razor
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@namespace TailBlazor.ToastServer.Shared
@using TailBlazor.Toast
@using Toast.Configuration
@using TailBlazor.Toast.Configuration
@inherits LayoutComponentBase


Expand Down
8 changes: 5 additions & 3 deletions samples/TailBlazor.ToastServer/TailBlazor.ToastServer.csproj
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\TailBlazor.Toast\TailBlazor.Toast.csproj" />
Expand Down
26 changes: 13 additions & 13 deletions samples/TailBlazor.ToastServer/_Imports.razor
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
@using System.Net.Http
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Authorization
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
@using TailBlazor.ToastServer
@using TailBlazor.ToastServer.Shared
@using TailBlazor.ToastServer.Toasts
@using TailBlazor.Toast.Services
@using TailBlazor.Toast
@using System.Net.Http
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Authorization
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
@using TailBlazor.ToastServer
@using TailBlazor.ToastServer.Shared
@using TailBlazor.ToastServer.Toasts
@using TailBlazor.Toast.Services
@using TailBlazor.Toast
2 changes: 1 addition & 1 deletion src/TailBlazor.Toast/Configuration/ToastInstance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ internal class ToastInstance
{
public Guid Id { get; set; }
public DateTime TimeStamp { get; set; }
public ToastSettings ToastSettings { get; set; }
public ToastSettings ToastSettings { get; set; } = default!;
}
}
6 changes: 3 additions & 3 deletions src/TailBlazor.Toast/Configuration/ToastSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ public ToastSettings(
IncludeIcons = includeIcons;
}

public string Heading { get; set; }
public RenderFragment Message { get; set; }
public string Class { get; set; }
public string? Heading { get; set; }
public RenderFragment Message { get; set; } = default!;
public string? Class { get; set; }
public HeroIcons.HeroIcon? Icon { get; set; }
public HeroIcons.IconStyle? IconStyle { get; set; }
public bool ShowProgressBar { get; set; }
Expand Down
18 changes: 12 additions & 6 deletions src/TailBlazor.Toast/CountdownTimer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ namespace TailBlazor.Toast
{
internal class CountdownTimer : IDisposable
{
private Timer _timer;
private int _timeout;
private int _countdownTotal;
private Timer? _timer;
private readonly int _timeout;
private readonly int _countdownTotal;
private int _percentComplete;

internal Action<int> OnTick;
internal Action OnElapsed;
internal Action<int>? OnTick;
internal Action? OnElapsed;

internal CountdownTimer(int timeout)
{
Expand All @@ -23,11 +23,12 @@ internal CountdownTimer(int timeout)

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

private void SetupTimer()
{
_timer?.Dispose();
_timer = new Timer(_timeout);
_timer.Elapsed += HandleTick;
_timer.AutoReset = false;
Expand All @@ -51,6 +52,11 @@ private void HandleTick(object sender, ElapsedEventArgs args)

public void Dispose()
{
if (_timer is null)
{
return;
}

_timer.Dispose();
_timer = null;
}
Expand Down
16 changes: 10 additions & 6 deletions src/TailBlazor.Toast/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@ namespace TailBlazor.Toast
{
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddTailBlazorToast(this IServiceCollection services, Action<ToastOptions>? configureOptions = null )
public static IServiceCollection AddTailBlazorToast(this IServiceCollection services, Action<ToastOptions>? configureOptions = null)
{
services.Configure<ToastOptions>(options =>
{
options.IncludeIcons = true;
configureOptions?.Invoke(options);
});
ArgumentNullException.ThrowIfNull(services);

services.AddOptions<ToastOptions>()
.Configure(options =>
{
options.IncludeIcons = true;
configureOptions?.Invoke(options);
});

return services.AddScoped<IToastService, ToastService>();
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/TailBlazor.Toast/Services/IToastService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ public interface IToastService
/// <summary>
/// Toast configuration options
/// </summary>
public ToastOptions _options { get; }
public ToastOptions Options { get; }
/// <summary>
/// A event that will be invoked when showing a toast
/// </summary>
event Action<ToastLevel, RenderFragment, string, Action> OnShow;
event Action<ToastLevel, RenderFragment, string, Action?>? OnShow;

/// <summary>
/// Shows a toast using the supplied fragment
Expand Down
8 changes: 4 additions & 4 deletions src/TailBlazor.Toast/Services/ToastService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ public class ToastService : IToastService
/// <summary>
/// Toast configuration options
/// </summary>
public ToastOptions _options { get; set; }
public ToastOptions Options { get; }

/// <summary>
/// ToastService parameterized constructor
/// </summary>
/// <param name="options">Toast configuration options</param>
public ToastService(IOptions<ToastOptions> options)
{
_options = options.Value;
Options = options.Value;
}
/// <summary>
/// A event that will be invoked when showing a toast
Expand All @@ -29,13 +29,13 @@ public ToastService(IOptions<ToastOptions> options)
/// <summary>
/// A event that will be invoked when showing a toast
/// </summary>
public event Action<ToastLevel, RenderFragment, string, Action> OnShow;
public event Action<ToastLevel, RenderFragment, string, Action?>? OnShow;

/// <summary>
/// Shows a toast using the fragment
/// </summary>
/// <param name="toast">RenderFragment of toast to display</param>
public void ShowToast(RenderFragment toast) => OnShow?.Invoke(ToastLevel.Custom, toast, String.Empty, null);
public void ShowToast(RenderFragment toast) => OnShow?.Invoke(ToastLevel.Custom, toast, string.Empty, null);

/// <summary>
/// Shows a toast using the supplied settings
Expand Down
90 changes: 45 additions & 45 deletions src/TailBlazor.Toast/TailBlazor.Toast.csproj
Original file line number Diff line number Diff line change
@@ -1,45 +1,45 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<PackageId>TailBlazor.Toast</PackageId>
<RootNamespace>TailBlazor.Toast</RootNamespace>
<Version>1.1.3</Version>
<Authors>Taylor Watson</Authors>
<IsPackage>true</IsPackage>
<PackageTags>Blazor; TailBlazorcss; TailBlazor css; tailwind; tailwindcss; toast; toasts;</PackageTags>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/TailBlazor/Toast</PackageProjectUrl>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/TailBlazor/Toast</RepositoryUrl>
<Description>
A shell toast system that's base uses TailBlazorcss 2.0. It's heavily inspired off Chris Sainty's Blazored.Toast and all credit goes to him for core functionality. This toast service has no styles, or content. You inject an entire renderfragment into the "ShowToast()" method to be able to create 100% customizable toasts. Finally the ability to create truly interactive toasts and not be limited to: info, success, etc.
</Description>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<IncludeSymbols>true</IncludeSymbols>
<PackageIcon>logo.png</PackageIcon>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
</PropertyGroup>
<ItemGroup>
<SupportedPlatform Include="browser" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="5.0.1" />
<PackageReference Include="TailBlazor.HeroIcons" Version="1.1.1" />
</ItemGroup>
<ItemGroup>
<None Include="../../logo.png" Pack="true" PackagePath="">
<LinkBase>assets</LinkBase>
</None>
<None Include="../../LICENSE" Pack="true" PackagePath="">
<LinkBase>assets</LinkBase>
</None>
</ItemGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk.Razor">

<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<PackageId>TailBlazor.Toast</PackageId>
<RootNamespace>TailBlazor.Toast</RootNamespace>
<Version>1.1.3</Version>
<Authors>Taylor Watson</Authors>
<IsPackage>true</IsPackage>
<PackageTags>Blazor; TailBlazorcss; TailBlazor css; tailwind; tailwindcss; toast; toasts;</PackageTags>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/TailBlazor/Toast</PackageProjectUrl>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/TailBlazor/Toast</RepositoryUrl>
<Description>
A shell toast system that's base uses TailBlazorcss 2.0. It's heavily inspired off Chris Sainty's Blazored.Toast and all credit goes to him for core functionality. This toast service has no styles, or content. You inject an entire renderfragment into the "ShowToast()" method to be able to create 100% customizable toasts. Finally the ability to create truly interactive toasts and not be limited to: info, success, etc.
</Description>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<PackageIcon>logo.png</PackageIcon>
</PropertyGroup>

<ItemGroup>
<SupportedPlatform Include="browser" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="9.0.0" />
<PackageReference Include="TailBlazor.HeroIcons" Version="1.1.1" />
</ItemGroup>

<ItemGroup>
<None Include="../../logo.png" Pack="true" PackagePath="">
<LinkBase>assets</LinkBase>
</None>
<None Include="../../LICENSE" Pack="true" PackagePath="">
<LinkBase>assets</LinkBase>
</None>
</ItemGroup>

</Project>
7 changes: 4 additions & 3 deletions src/TailBlazor.Toast/TailBlazorToast.razor
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
@using Microsoft.AspNetCore.Components.Web
@using TailBlazor.Toast.Configuration
@namespace TailBlazor.Toast
@attribute [RenderModeInteractiveAuto]

<div class="w-full m-5 pointer-events-auto">
<CascadingValue Value=ToastId>
<CascadingValue Value="@ToastId">
@if (ToastSettings.Level == Services.ToastLevel.Custom)
{
@(ToastSettings.Message)
}
else
{
<div class="p-4 mb-5 bg-white rounded-lg shadow-lg pointer-events-auto">
<div class="p-4 mb-5 bg-white rounded-lg shadow-lg pointer-events-auto" @onclick="ToastClick">
<div class="flex items-start">
@if (ToastSettings.IncludeIcons)
{
Expand All @@ -23,7 +24,7 @@
<p class="mt-1 text-sm text-gray-500">@(ToastSettings.Message)</p>
</div>
<div class="flex flex-shrink-0 ml-4">
<button @onclick="@Close"
<button @onclick="@Close" @onclick:stopPropagation="true"
class="inline-flex text-gray-400 bg-white rounded-md hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
<span class="sr-only">Close</span>
<svg class="w-5 h-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"
Expand Down
Loading