An automation framework to help you build Blazor component libary easier and faster.
Features
Easy and automation build parameters for component
Easy to customize and personalize component building
Easy to build a flexible dynamic component structure
Easy interoption between code and javascript
Modular implementation for automation of component building
Strong extensions and utilities of RenderTreeBuilder
Copy @inherits BlazorComponentBase
<button @attributes="AdditionalAttributes">
@ChildContent
</button>
@code{
[CssClass("btn")]
public Button()
{
}
[Parameter][CssClass("active")]public bool Active { get; set; }
[Parameter][CssClass("btn-")]public Color? Color { get; set; }
[Parameter]public RenderFragment? ChildContent { get; set; }
[Parameter][HtmlData("tooltip")]public string? Tooltip { get; set; }
[Parameter][HtmlEvent("onclick")]public EventCallback<ClickEventArgs> OnClick { get; set; }
[Parameter][HtmlAttribute]public string? Title { get; set; }
public enum Color
{
Primary,
Secondary,
[CssClass("info")]Information,
}
}
In Button.cs
component class for full automation features
Copy [ HtmlTag ( "button" )]
[ CssClass ( "btn" )]
public class Button : BlazorComponentBase , IHasChildContent , IHasOnClick
{
[ Parameter ][ CssClass ( "active" )] public bool Active { get ; set ; }
[ Parameter ][ CssClass ( "btn-" )] public Color ? Color { get ; set ; }
[ Parameter ] public RenderFragment ? ChildContent { get ; set ; }
[ Parameter ][ HtmlData ( "tooltip" )] public string ? Tooltip { get ; set ; }
[ Parameter ][ HtmlEvent ( "onclick" )] public EventCallback < ClickEventArgs > OnClick { get ; set ;
[ Parameter ][ HtmlAttribute ]public string? Title { get ; set ; }
}
public enum Color
{
Primary ,
Secondary ,
[ CssClass ( "info" )]Information ,
}
Copy <!--razor-->
<Button Color="Color.Primary">Submit</Button>
<!--html-->
<button class="btn btn-primary">Submit</button>
<!--razor-->
<Button Active Tooltip="active button" Color="Color.Information" Title="click me">Active Button</Button>
<!--html-->
<button class="btn btn-info active" data-tooltip="active button" title="click me">Active Button</button>
Copy //in app.js
export function display (){
// ...your code
}
Copy [ Inject ]IJSRuntime JS { get; set; }
var js = await JS . Value .ImportAsync( "./app.js" );
js .display(); // same as function name
Copy JS . Value .EvaluateAsync(window => {
window . console .log( "log" )
});
JS . Value .EvaludateAsync( @"
console.log(\" log\ ");
")
Copy protected override void BuildCssClass ( ICssClassBuilder builder)
{
if ( builder .Contains( "annotation-enter" ))
{
builder .Remove( "annotation-exist" );
}
else
{
builder .Append( "annotation-enter" ).Append( "annotation-exist" );
}
}
Copy protected override void BuildAttributes ( IDictionary < string , object > attributes)
{
attributes [ "onclick" ] = HtmlHelper . Event .Create( this , () => { .. . });
if ( attrbutes .ContainKey( "data-toggle" ))
{
attributes [ "data-toggle" ] = "collapse" ;
}
}
Copy protected override void BuildRenderTree ( RenderTreeBuilder builder)
{
builder .Open( "div" )
.Class( "my-class" , (IsActive , "active" ) , ( ! string .IsNullOrEmpty(Name) , "text-block" ))
.Style(( Size . HasValue , $"font-size:{Size}px" ))
.Content( "hello world" )
.Close();
builder .CreateElement( 10 , "span" , "hello" , attributes : new { @class = "title-span" });
}
Copy protected override void BuildRenderTree ( RenderTreeBuilder builder)
{
builder .Open < Button > ()
.Class( "my-class" , (IsActive , "active" ) , ( ! string .IsNullOrEmpty(Name) , "text-block" ))
.Style(( Size . HasValue , $"font-size:{Size}px" ))
.Content(ChildContent)
.Close();
builder .CreateComponent < NavLink > ( 0 , "Home" , new { NavLinkMatch = NavLinkMatch . All , ActiveCssClass = "nav-active" })
}
In .razor file
For List.razor
file be parent component
Copy <ul @attributes="AdditionalAttributes">
<CascadingValue Value="this">
@ChildContent
</CascadingValue>
</ul>
For ListItem.razor
file be child of List.razor
component
Copy <li @attributes="AdditionalAttributes">@ChildContent</li>
@code{
[ChildComponent(typeof(List))]
public ListItem()
{
}
[CascadingParameter] public List CascadedList { get; set; }
[Parameter] public RenderFragment? ChildContent { get; set; }
}
In RenderTreeBuilder
Copy [ ParentComponent ] //be cascading parameter for this component
[ HtmlTag ( "ul" )]
public class List : BlazorComponentBase , IHasChildContent
{
}
For ListItem
component class
Copy [ ChildComponent ( typeof ( List ))] //Strong association with List
[ HtmlTag ( "li" )]
public class ListItem : BlazorComponentBase , IHasChildContent
{
[ CascadingParameter ] public List CascadedList { get ; set ; }
[ Parameter ] public RenderFragment ? ChildContent { get ; set ; }
}
Use in blazor
Copy <List>
<ListItem>...</ListItem>
</List>
<ListItem /> <!--throw exception because ListItem must be the child component of List coponent witch defined ChildComponentAttribute in ListItem-->
Copy <div class="@GetCssClass">
...
</div>
@code{
string GetCssClass => HtmlHelper.Class.Append("btn-primary").Append("active", Actived).ToString();
}
Dynamic element attribute
Copy builder .CreateElement( 0 , "span" , attributes :
new {
@class = HtmlHelper . Class
.Append( "btn-primary" )
.Append( "active" , Actived) ,
style = HtmlHelper . Style .Append( $"width:{Width}px" ) ,
onclick = HtmlHelper . Event .Create < MouseEventArgs > ( this , e => { //...click... });
});
You can intercept the lifecycle of component
Copy public class LogInterceptor : ComponentInterceptorBase
{
private readonly ILogger < LogInterceptor > _logger;
public LogInterceptor ( ILogger < LogInterceptor > logger)
{
_logger = logger;
}
//Run in SetParameterAsync method is called
public override void InterceptSetParameters ( IBlazorComponent component , ParameterView parameters)
{
foreach ( var item in parameters)
{
_logger .LogDebug( $"Key:{ item . Name }, Value:{ item . Value }" );
}
}
}
Copy builder . Services .AddComponentBuilder(configure => {
configure . Interceptors .Add( new LogInterceptor ());
})
Copy Install-Package ComponentBuilder
Copy builder . Services .AddComponentBuilder();
Use ComponentBuilder.Templates
to generate a razor component library solution and online demo site
Copy dotnet new install ComponentBuilder.Templates
dotnet new blazor - sln - n {YourRazorLibraryName}