# ComponentBuilder
**Repository Path**: AchievedOwner/ComponentBuilder
## Basic Information
- **Project Name**: ComponentBuilder
- **Description**: A framework can easily help you to create blazor component from code behind.
- **Primary Language**: C#
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2021-12-23
- **Last Updated**: 2024-01-27
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# ComponentBuilder
Easy to create a Blazor Component Library with automation features supports both razor file way and RenderTreeBuilder way.
[中文介绍](README.zh-cn.md) | [Quick Start](./docs/readme.md) | [Document](https://playermaker.gitbook.io/componentbuilder/english/introduction)



## :sparkles: Features
* Attribute first, easy define CSS from parameters
* Easy to associate with components via Attributes
* Cusomization CSS and attributes of component by coding logic
* Both supports `.razor` file or `RenderTreeBuilder` to create component
* Support `Pre-definition` for components with simular parameters
* Dynamic JS interoption
* New lifecycle definition of Component with interceptor design pattern
* Renderer pipeline pattern to regonize dynamic render of components
* More extensions for `RenderTreeBuilder` instance
* Create element with Fluent API
## :rainbow: Quick Start
* In `Button.razor` file
```html
@inherits BlazorComponentBase
@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][HtmlAttribute("onclick")]public EventCallback 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
```csharp
[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 OnClick { get; set;
[Parameter][HtmlAttribute]public string? Title { get; set; }
}
public enum Color
{
Primary,
Secondary,
[CssClass("info")]Information,
}
```
* Use component
```html
```
## :key: JS Interoption
* Import modules
```js
//in app.js
export function display(){
// ...your code
}
```
```csharp
[Inject]IJSRuntime JS { get; set; }
var js = await JS.Value.ImportAsync("./app.js");
js.display(); // same as function name
```
* Evaluate js string
```csharp
JS.Value.EvaluateAsync(window => {
window.console.log("log")
});
JS.Value.EvaludateAsync(@"
console.log(\"log\");
")
```
* JS invoke C# code
```csharp
JS.Value.InvokeVoidAsync("myFunction", CallbackFactory.Create(arg=> {
//get arg from js
}));
JS.Value.InvokeVoidAsync("calculate", CallbackFactory.Create((arg1,arg2)=> {
//get value of arg1,arg2 from js
}))
```
```js
function myFunction(dotNetRef){
dotNetRef.invokeMethodAsync("Invoke", "arg");
}
function calculate(dotNetRef){
dotNetRef.invokeMethodAsync("Invoke", 1, 2);
}
```
## :information_source: Logical CSS/Style/Attributes
* Logical CSS
```csharp
protected override void BuildCssClass(ICssClassBuilder builder)
{
if(builder.Contains("annotation-enter"))
{
builder.Remove("annotation-exist");
}
else
{
builder.Append("annotation-enter").Append("annotation-exist");
}
}
```
* Logical Attributes
```csharp
protected override void BuildAttributes(IDictionary attributes)
{
attributes["onclick"] = HtmlHelper.Event.Create(this, ()=>{ ... });
if(attrbutes.ContainKey("data-toggle"))
{
attributes["data-toggle"] = "collapse";
}
}
```
## :palm_tree: Fluent API
```csharp
builder.Div()
.Class("my-class")
.Class("active", IsActive)
.Class("text-block", !string.IsNullOrEmpty(Name))
.Style($"font-size:{Size}px", Size.HasValue)
.Content("hello world")
.Close();
builder.Component