# SbTreeView A hierarchical tree view component for displaying nested data structures. ## Type Parameters | Parameter | Description | |-----------|-------------| | TItem | The type of items in the tree | ## Parameters | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | Items | IEnumerable\ | Empty | Root items | | ChildSelector | Func\\> | Returns empty | Function to get child items | | TextSelector | Func\ | ToString() | Function to get item display text | | IconSelector | Func\? | null | Function to get item icon name | | IsExpandedSelector | Func\? | null | Function to check if item is expanded | | IsSelectedSelector | Func\? | null | Function to check if item is selected | | SelectedItem | TItem? | null | Currently selected item | | ShowCheckboxes | bool | false | Whether to show checkboxes | | CheckedItems | HashSet\ | new() | Set of checked items | | Class | string? | null | Additional CSS classes | ## Events | Event | Type | Description | |-------|------|-------------| | SelectedItemChanged | EventCallback\ | Fired when item is selected | | OnToggle | EventCallback\ | Fired when item is expanded/collapsed | | CheckedItemsChanged | EventCallback\\> | Fired when checked items change | ## CSS Classes - `sb-treeview` - Base class ## Accessibility - Uses `role="tree"` for the container - Uses `role="treeitem"` for items - Uses `role="group"` for child containers - Uses `aria-level` for nesting depth - Uses `aria-expanded` for expandable items ## Examples ### Basic Usage ```razor @code { private List rootNodes = new() { new TreeNode("Documents", new[] { new TreeNode("Work"), new TreeNode("Personal") }), new TreeNode("Pictures"), new TreeNode("Music") }; public class TreeNode { public string Name { get; set; } public List Children { get; set; } = new(); public TreeNode(string name, IEnumerable? children = null) { Name = name; Children = children?.ToList() ?? new(); } } } ``` ### With Icons ```razor @code { private List files = new() { new FileNode("src", isFolder: true, children: new[] { new FileNode("components", isFolder: true), new FileNode("App.razor"), new FileNode("Program.cs") }), new FileNode("README.md") }; } ``` ### Selectable Tree ```razor Selected: @(selectedCategory?.Name ?? "None") @code { private Category? selectedCategory; private List categories = /* ... */; } ``` ### With Checkboxes ```razor Save (@checkedPermissions.Count selected) @code { private HashSet checkedPermissions = new(); private List permissions = new() { new Permission("Users", new[] { new Permission("View"), new Permission("Create"), new Permission("Edit"), new Permission("Delete") }), new Permission("Reports", new[] { new Permission("View"), new Permission("Export") }) }; } ``` ### Controlled Expansion ```razor @code { private HashSet expandedNodes = new() { 1, 2 }; private void HandleToggle(TreeNode node) { if (expandedNodes.Contains(node.Id)) expandedNodes.Remove(node.Id); else expandedNodes.Add(node.Id); } } ``` ### File Explorer ```razor @code { private List fileSystem; private FileSystemItem? selectedFile; private string? GetIcon(FileSystemItem item) => item.Type switch { FileType.Folder => "folder", FileType.File => GetFileIcon(item.Extension), _ => null }; private string GetFileIcon(string? ext) => ext switch { ".cs" => "file-code", ".json" => "file-json", ".md" => "file-text", ".jpg" or ".png" => "image", _ => "file" }; private async Task LoadChildren(FileSystemItem folder) { if (folder.Type == FileType.Folder && !folder.ChildrenLoaded) { folder.Children = await LoadFromDisk(folder.Path); folder.ChildrenLoaded = true; } } } ``` ### Organization Hierarchy ```razor @if (selectedEmployee != null) { @selectedEmployee.Name @selectedEmployee.Title @selectedEmployee.Email Direct Reports: @selectedEmployee.DirectReports.Count } ```