Useful components and utilities for Blazor developers
Your new component base class with:
- typed
Logger
instance IsInitialized
property to simplify your rendering logic for asynchronously initialized components!Disposer
object to register disposables at creation time!InvokeAsyncStateHasChanged()
method- Support for Integrations
and more to come!
Per component:
@inherits BlazingDev.BlazorToolkit.Components.BzComponentBase
Globally:
Locate _Imports.razor
and add the following line to set the base component for all *.razor
files in the same
directory and subdirectories:
@inherits BlazingDev.BlazorToolkit.Components.BzComponentBase
@* IsInitialized from base class *@
@if (IsInitialized)
{
// render product and reviews
}
else
{
<LoadingSpinner />
}
@code {
IDisposable? _someDisposable = null;
ProductDto? _product = null;
List<ProductReviewDto>? _reviews = null;
protected override async Task OnInitializedAsync()
{
_someDisposable = GetSomeDisposable();
_product = await ProductService.GetProductAsync(5);
_reviews = await ProductService.GetProductReviewsAsync(5);
// BzAsyncDisposer from base class
Disposer.Add(_someDisposable);
var subscription = SubscriptionService.Subscribe("important-messages", HandleImportantMessage);
// Logger from base class
Logger.LogInformation("Got subscription {SubscriptionId}", subscription.Id);
Disposer.Add(subscription);
SubscriptionService.ConnectionLost += HandleConnectionLost;
Disposer.Add(() => SubscriptionService.ConnectionLost -= HandleConnectionLost);
Disposer.Add(SayGoodbyeAsync);
}
private void HandleConnectionLost(object sender, EventArgs e)
{
ShowReconnectOverlay = true;
// little simplified method from base class
InvokeAsyncStateHasChanged();
}
}
Provides utility methods regarding components.
With the following methods you can retrieve a component's route (@page "/this-is-the-route"
).
Useful if you want to create links to other components and you don't want to have magic strings in your code.
// returns the first defined route or null for non-routable components
BzComponentTool.TryGetRoute<PotentiallyRoutableComponent>();
BzComponentTool.TryGetRoute(typeof(PotentiallyRoutableComponent));
// returns the first defined route or throws for non-routable components
BzComponentTool.GetRoute<SomePage>();
BzComponentTool.GetRoute(typeof(SomePage));
// returns zero-to-many items
BzComponentTool.TryGetRoutes<PageWithMultipleRoutes>();
BzComponentTool.TryGetRoutes(typeof(PageWithMultipleRoutes));
Use the BzMenuItemAttribute
to specify menu items at component level.
For extra laziness you can use the BzComponentTool.GetAllMenuItemsFromAssembly(assembly)
method :)
@page "/about"
@attribute [BzMenuItem(Name = "About", Icon = "people", Sorting = 500)]
BzComponentTool.GetMenuItem<AboutPage>(); // requires ( @page OR [Route] ) AND [BzMenuItem]
BzComponentTool.TryGetMenuItem<AboutPage>(); // returns null if anything required is missing
// NavMenu.razor
@foreach (var item in BzComponentTool.GetAllMenuItemsFromAssembly(GetType().Assembly))
{
<MyNavItem MenuItem="item"/>
}
A blazor component that wraps a Timer instance.
Automatically handles:
- Creating the
Timer
- Calling
InvokeAsync()
- Calling
StateHasChanged()
when using theOnElapsed
EventCallback
OnElapsedAction
when you want to manually decide if any re-rendering is neededtry-catch
of the elapsed handlers- disposing the timer when the component is unmounted
And you can use ShowControls
for testing purposes which let you override the Enabled
and Interval
setting!
<BzTimerComponent Name="PriceRefreshTimer" Interval="5000" OnElapsed="HandleUpdatePriceTimerElapsed" />
A utility class to help creating CSS classes lists.
- static
Create
methods to not use spaces (sometimes handy in razor files) Add(className)
,Add(listOfClassNames)
,AddIf(condition, className)
Remove(className)
,RemoveIf(condition, className)
- automatically trimes classNames
- ignores duplicates and no-content classNames
- use
Build()
orToString()
to get your final string
@{
var cssClasses = BzCssClassBuilder.Create("my-button")
.Add("button-primary")
.AddIf(isOutline, "button-outline")
.Add(SomeSettings.AdditionalButtonClasses) // e.g. theme-specific
.Build()
}
<button class="@cssClasses">...</button>
A utility class for building CSS styles conditionally and fluently.
var style = new BzCssStyleBuilder()
.Add("color", "red")
.Add("font-size", UserFontSize, "em")
.AddIf(isBold, "font-weight", "bold")
.AddIf(concreteWidth, "width", CalculateWidthFunction, "px")
.Add(Style) // from component parameter
.Build();
Predefined render modes without prerender
per component, e.g. in App.razor
:
<Routes @rendermode="BzRenderMode.InteractiveServerNoPrerender"/>
If you add the following line in _Imports.razor
, you can omit the BzRenderMode
prefix:
@using static BlazingDev.BlazorToolkit.Components.BzRenderMode