diff --git a/README.md b/README.md
index c229dcd..838c6eb 100644
--- a/README.md
+++ b/README.md
@@ -83,6 +83,7 @@ Add required `CSS` and `Javascript` packages into the `index.html` file.
- [Toast](#toast)
- [Toggle](#toggle)
- [Tooltip](#tooltip)
+- [Tree](#tree)
- [Upload](#upload)
- [Form Validation](#form-validation)
- [Workflow](#workflow)
@@ -695,7 +696,67 @@ toast.ShowToast("test message", "info");
```
-- [ ] Tree
+## Tree
+
+```html
+
+
+
+```
+
+```csharp
+Tree tree;
+
+Dictionary treeNodes = new();
+
+treeNodes.Add("root", new TreeNode()
+{
+ Id = "root",
+ HasChildren = true,
+ Children = new List(){"sample"}
+});
+
+treeNodes.Add("sample", new TreeNode()
+{
+ Id = "sample",
+ Data = new TreeData()
+ {
+ Name = "Sample"
+ },
+ HasChildren = true,
+ Children = new List(){"sample-child-1", "sample-child-2"}
+});
+
+treeNodes.Add("sample-child-1", new TreeNode()
+{
+ Id = "sample-child-1",
+ Data = new TreeData()
+ {
+ Name = "Sample Child 1"
+ },
+ HasChildren = false,
+ Children = new List() {}
+});
+
+treeNodes.Add("sample-child-2", new TreeNode()
+ {
+ Id = "sample-child-2",
+ Data = new TreeData()
+ {
+ Name = "Sample Child 2"
+ },
+ HasChildren = false,
+ Children = new List() { }
+ });
+
+
+tree.TreeModel = treeNodes;
+```
+
## Upload
```html
diff --git a/SiemensIXBlazor/Components/Tree/Tree.razor b/SiemensIXBlazor/Components/Tree/Tree.razor
new file mode 100644
index 0000000..fb46dd0
--- /dev/null
+++ b/SiemensIXBlazor/Components/Tree/Tree.razor
@@ -0,0 +1,10 @@
+@using Microsoft.JSInterop;
+@inject IJSRuntime JSRuntime
+@inherits IXBaseComponent
+
+
diff --git a/SiemensIXBlazor/Components/Tree/Tree.razor.cs b/SiemensIXBlazor/Components/Tree/Tree.razor.cs
new file mode 100644
index 0000000..009fd6e
--- /dev/null
+++ b/SiemensIXBlazor/Components/Tree/Tree.razor.cs
@@ -0,0 +1,110 @@
+using Microsoft.AspNetCore.Components;
+using Microsoft.JSInterop;
+using Newtonsoft.Json;
+using SiemensIXBlazor.Interops;
+using SiemensIXBlazor.Objects;
+using System.Dynamic;
+using System.Text.Json;
+
+namespace SiemensIXBlazor.Components.Tree
+{
+ public partial class Tree
+ {
+ private Dictionary? _treeModel;
+ private Dictionary? _treeContext;
+ private Lazy>? moduleTask;
+ private BaseInterop? _interop;
+
+ [Parameter, EditorRequired]
+ public string Id { get; set; } = string.Empty;
+ public Dictionary? TreeModel
+ {
+ get => _treeModel;
+ set
+ {
+ _treeModel = value;
+ InitialParameter("setTreeModel", _treeModel);
+ }
+ }
+ public Dictionary? TreeContext
+ {
+ get => _treeContext;
+ set
+ {
+ _treeContext = value;
+ InitialParameter("setTreeContext", _treeContext);
+ }
+ }
+ [Parameter]
+ public string? Root { get; set; }
+ [Parameter]
+ public EventCallback> ContextChangedEvent { get; set; }
+ [Parameter]
+ public EventCallback NodeRemovedEvent { get; set; }
+ [Parameter]
+ public EventCallback NodeClickedEvent { get; set; }
+ [Parameter]
+ public EventCallback NodeToggledEvent { get; set; }
+
+ protected override void OnAfterRender(bool firstRender)
+ {
+ if (firstRender)
+ {
+ _interop = new(JSRuntime);
+
+ Task.Run(async () =>
+ {
+ await _interop.AddEventListener(this, Id, "contextChange", "ContextChanged");
+ await _interop.AddEventListener(this, Id, "nodeRemoved", "NodeRemoved");
+ await _interop.AddEventListener(this, Id, "nodeClicked", "NodeClicked");
+ await _interop.AddEventListener(this, Id, "nodeToggled", "NodeToggled");
+ });
+ }
+ }
+
+ private void InitialParameter(string functionName, object param)
+ {
+
+ moduleTask = new(() => JSRuntime.InvokeAsync(
+ "import", $"./_content/SiemensIXBlazor/js/interops/treeInterop.js").AsTask());
+
+ Task.Run(async () =>
+ {
+ var module = await moduleTask.Value;
+ if (module != null)
+ {
+ var serObj = JsonConvert.SerializeObject(param);
+ await module.InvokeVoidAsync(functionName, Id, JsonConvert.SerializeObject(param));
+ }
+ });
+ }
+
+ [JSInvokable]
+ public async Task ContextChanged(JsonElement context)
+ {
+ string jsonDataText = context.GetRawText();
+ Dictionary? changedContext = JsonConvert.DeserializeObject>(jsonDataText);
+ await ContextChangedEvent.InvokeAsync(changedContext);
+ }
+
+ [JSInvokable]
+ public async Task NodeRemoved()
+ {
+ await NodeRemovedEvent.InvokeAsync();
+ }
+
+ [JSInvokable]
+ public async Task NodeClicked(string label)
+ {
+ await NodeClickedEvent.InvokeAsync(label);
+ }
+
+ [JSInvokable]
+ public async Task NodeToggled(JsonElement toggledNode)
+ {
+ string jsonDataText = toggledNode.GetRawText();
+ TreeNodeToggledEventResult result = JsonConvert.DeserializeObject(jsonDataText);
+ await NodeToggledEvent.InvokeAsync(result);
+ }
+ }
+}
diff --git a/SiemensIXBlazor/Objects/TreeContextNode.cs b/SiemensIXBlazor/Objects/TreeContextNode.cs
new file mode 100644
index 0000000..3bf8c67
--- /dev/null
+++ b/SiemensIXBlazor/Objects/TreeContextNode.cs
@@ -0,0 +1,12 @@
+using Newtonsoft.Json;
+
+namespace SiemensIXBlazor.Objects
+{
+ public class TreeContextNode
+ {
+ [JsonProperty("isExpanded")]
+ public bool IsExpanded { get; set; }
+ [JsonProperty("isSelected")]
+ public bool IsSelected { get; set; }
+ }
+}
diff --git a/SiemensIXBlazor/Objects/TreeData.cs b/SiemensIXBlazor/Objects/TreeData.cs
new file mode 100644
index 0000000..f6b03de
--- /dev/null
+++ b/SiemensIXBlazor/Objects/TreeData.cs
@@ -0,0 +1,10 @@
+using Newtonsoft.Json;
+
+namespace SiemensIXBlazor.Objects
+{
+ public class TreeData
+ {
+ [JsonProperty("name")]
+ public string? Name { get; set; }
+ }
+}
diff --git a/SiemensIXBlazor/Objects/TreeNode.cs b/SiemensIXBlazor/Objects/TreeNode.cs
new file mode 100644
index 0000000..6de820e
--- /dev/null
+++ b/SiemensIXBlazor/Objects/TreeNode.cs
@@ -0,0 +1,16 @@
+using Newtonsoft.Json;
+
+namespace SiemensIXBlazor.Objects
+{
+ public class TreeNode
+ {
+ [JsonProperty("id")]
+ public string? Id { get; set; }
+ [JsonProperty("data")]
+ public TreeData? Data { get; set; }
+ [JsonProperty("hasChildren")]
+ public bool HasChildren { get; set; }
+ [JsonProperty("children")]
+ public List? Children { get; set; }
+ }
+}
diff --git a/SiemensIXBlazor/Objects/TreeNodeToggledEventResult.cs b/SiemensIXBlazor/Objects/TreeNodeToggledEventResult.cs
new file mode 100644
index 0000000..687af66
--- /dev/null
+++ b/SiemensIXBlazor/Objects/TreeNodeToggledEventResult.cs
@@ -0,0 +1,12 @@
+using Newtonsoft.Json;
+
+namespace SiemensIXBlazor.Objects
+{
+ public class TreeNodeToggledEventResult
+ {
+ [JsonProperty("id")]
+ public string Id { get; set; }
+ [JsonProperty("isExpaned")]
+ public bool IsExpaned { get; set; }
+ }
+}
diff --git a/SiemensIXBlazor/wwwroot/js/interops/treeInterop.js b/SiemensIXBlazor/wwwroot/js/interops/treeInterop.js
new file mode 100644
index 0000000..e81cd14
--- /dev/null
+++ b/SiemensIXBlazor/wwwroot/js/interops/treeInterop.js
@@ -0,0 +1,20 @@
+export function setTreeModel(id, treeModel) {
+ try {
+ const element = document.getElementById(id);
+ element.model = JSON.parse(treeModel);
+ console.log(element, JSON.parse(treeModel));
+ }
+ catch {
+
+ }
+}
+
+export function setTreeContext(id, treeContext) {
+ try {
+ const element = document.getElementById(id);
+ element.context = JSON.parse(treeContext);
+ }
+ catch {
+
+ }
+}
\ No newline at end of file