Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
ο»Ώ#pragma checksum "E:\fluentui-blazor-community-extensions\src\Core\Components\FloatingButton\FluentCxFloatingButton.razor" "{8829d00f-11b8-4213-878b-770e8597ac16}" "c63f5265c750f1122162591bd5f009c3206d869a26fc294ae0f0d5c505f1fbd2"
ο»Ώ#pragma checksum "D:\TFS\Personnels\Microsoft\src\Core\Components\FloatingButton\FluentCxFloatingButton.razor" "{8829d00f-11b8-4213-878b-770e8597ac16}" "c63f5265c750f1122162591bd5f009c3206d869a26fc294ae0f0d5c505f1fbd2"
// <auto-generated/>
#pragma warning disable 1591
namespace
#nullable restore
#line (1,12)-(1,48) "E:\fluentui-blazor-community-extensions\src\Core\Components\FloatingButton\FluentCxFloatingButton.razor"
#line (1,12)-(1,48) "D:\TFS\Personnels\Microsoft\src\Core\Components\FloatingButton\FluentCxFloatingButton.razor"
FluentUI.Blazor.Community.Components

#line default
Expand All @@ -17,23 +17,29 @@ namespace
using global::System.Threading.Tasks;
using global::Microsoft.AspNetCore.Components;
#nullable restore
#line (1,2)-(1,43) "E:\fluentui-blazor-community-extensions\src\Core\_Imports.razor"
#line (1,2)-(1,43) "D:\TFS\Personnels\Microsoft\src\Core\_Imports.razor"
using Microsoft.AspNetCore.Components.Web

#nullable disable
;
#nullable restore
#line (2,2)-(2,48) "E:\fluentui-blazor-community-extensions\src\Core\_Imports.razor"
#line (2,2)-(2,48) "D:\TFS\Personnels\Microsoft\src\Core\_Imports.razor"
using Microsoft.FluentUI.AspNetCore.Components

#nullable disable
;
#nullable restore
#line (3,2)-(3,62) "D:\TFS\Personnels\Microsoft\src\Core\_Imports.razor"
using Microsoft.FluentUI.AspNetCore.Components.Icons.Regular

#nullable disable
;
#line default
#line hidden
#nullable restore
public partial class FluentCxFloatingButton :
#nullable restore
#line (2,11)-(2,23) "E:\fluentui-blazor-community-extensions\src\Core\Components\FloatingButton\FluentCxFloatingButton.razor"
#line (2,11)-(2,23) "D:\TFS\Personnels\Microsoft\src\Core\Components\FloatingButton\FluentCxFloatingButton.razor"
FluentButton

#line default
Expand All @@ -46,7 +52,7 @@ public partial class FluentCxFloatingButton :
protected override void BuildRenderTree(global::Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
{
#nullable restore
#line (4,2)-(8,1) "E:\fluentui-blazor-community-extensions\src\Core\Components\FloatingButton\FluentCxFloatingButton.razor"
#line (4,2)-(8,1) "D:\TFS\Personnels\Microsoft\src\Core\Components\FloatingButton\FluentCxFloatingButton.razor"
if (IsVisible)
{
base.BuildRenderTree(__builder);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ο»Ώ#pragma checksum "E:\fluentui-blazor-community-extensions\src\Core\_Imports.razor" "{8829d00f-11b8-4213-878b-770e8597ac16}" "d152b9916444bc13c0c63bebf3aba36aa917067fe32d156426ae9a3d93832788"
ο»Ώ#pragma checksum "D:\TFS\Personnels\Microsoft\src\Core\_Imports.razor" "{8829d00f-11b8-4213-878b-770e8597ac16}" "88efe84afb375a2c8c276875a99944a7d2510886a9a934d833bf5b3a39ca71a8"
// <auto-generated/>
#pragma warning disable 1591
namespace FluentUI.Blazor.Community.Components
Expand All @@ -10,15 +10,21 @@ namespace FluentUI.Blazor.Community.Components
using global::System.Threading.Tasks;
using global::Microsoft.AspNetCore.Components;
#nullable restore
#line (1,2)-(1,43) "E:\fluentui-blazor-community-extensions\src\Core\_Imports.razor"
#line (1,2)-(1,43) "D:\TFS\Personnels\Microsoft\src\Core\_Imports.razor"
using Microsoft.AspNetCore.Components.Web

#nullable disable
;
#nullable restore
#line (2,2)-(2,48) "E:\fluentui-blazor-community-extensions\src\Core\_Imports.razor"
#line (2,2)-(2,48) "D:\TFS\Personnels\Microsoft\src\Core\_Imports.razor"
using Microsoft.FluentUI.AspNetCore.Components

#nullable disable
;
#nullable restore
#line (3,2)-(3,62) "D:\TFS\Personnels\Microsoft\src\Core\_Imports.razor"
using Microsoft.FluentUI.AspNetCore.Components.Icons.Regular

#nullable disable
;
#line default
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
ο»Ώ@using FluentUI.Blazor.Community.Components.TrailMenu
<p>
The TrailMenu component can only be used with a list of items.
This list can be build with the <code>TrailMenuFactory</code> class in a fluent way.
</p>


<FluentCxTrailMenu Root="@_root" />

@code {
private readonly ITrailMenuItem _root;

public DefaultExample()
{
_root = TrailMenuFactory.Create("root", "Root")
.AddRoot("books", "Books")
.Add("blue-morpho", "Blue Morpho")
.AddSibling("stone-worm", "Stone Worm")
.AddRoot("movies", "Movies")
.Add("matrix", "Matrix")
.AddSibling("matrix-reloaded", "Matrix Reloaded")
.AddSibling("matrix-revolution", "Matrix Revolution")
.AddRoot("music", "Music")
.Add("pink-floyd", "Pink Floyd")
.AddSibling("led-zeppelin", "Led Zeppelin")
.AddSibling("the-beatles", "The Beatles")
.AddRoot("games", "Games")
.Add("yakuza", "Yakuza")
.Add("yakuza-kiwami", "Yakuza Kiwami")
.AddSibling("yakuza-kiwami-2", "Yakuza Kiwami 2")
.AddSibling("yakuza-3", "Yakuza 3")
.AddSibling("yakuza-0", "Yakuza 0")
.UpToParent("games")
.Add("the-witcher", "The Witcher")
.Add("the-witcher-1", "The Witcher 1")
.AddSibling("the-witcher-2", "The Witcher 2")
.AddSibling("the-witcher-3", "The Witcher 3")
.UpToParent("games")
.Add("fuga", "Fuga, Melodies of Steel")
.Add("fuga-1", "Fuga 1")
.AddSibling("fuga-2", "Fuga 2")
.AddSibling("fuga-3", "Fuga 3")
.UpToParent("games")
.Add("cyberpunk", "Cyberpunk 2077")
.AddSibling("elden-ring", "Elden Ring")
.Build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
ο»Ώ@using FluentUI.Blazor.Community.Components.TrailMenu
<p>
The TrailMenu component can only be used with a list of items and a start path.
This list can be build with the <code>TrailMenuFactory</code> class in a fluent way.
</p>


<FluentCxTrailMenu Root="@_root" Path="@_path"/>

@code {
private readonly ITrailMenuItem _root;
private string _path = "root/games/yakuza/yakuza-kiwami";

public RootAndPathExample()
{
_root = TrailMenuFactory.Create("root", "Root")
.AddRoot("books", "Books")
.Add("blue-morpho", "Blue Morpho")
.AddSibling("stone-worm", "Stone Worm")
.AddRoot("movies", "Movies")
.Add("matrix", "Matrix")
.AddSibling("matrix-reloaded", "Matrix Reloaded")
.AddSibling("matrix-revolution", "Matrix Revolution")
.AddRoot("music", "Music")
.Add("pink-floyd", "Pink Floyd")
.AddSibling("led-zeppelin", "Led Zeppelin")
.AddSibling("the-beatles", "The Beatles")
.AddRoot("games", "Games")
.Add("yakuza", "Yakuza")
.Add("yakuza-kiwami", "Yakuza Kiwami")
.AddSibling("yakuza-kiwami-2", "Yakuza Kiwami 2")
.AddSibling("yakuza-3", "Yakuza 3")
.AddSibling("yakuza-0", "Yakuza 0")
.UpToParent("games")
.Add("the-witcher", "The Witcher")
.Add("the-witcher-1", "The Witcher 1")
.AddSibling("the-witcher-2", "The Witcher 2")
.AddSibling("the-witcher-3", "The Witcher 3")
.UpToParent("games")
.Add("fuga", "Fuga, Melodies of Steel")
.Add("fuga-1", "Fuga 1")
.AddSibling("fuga-2", "Fuga 2")
.AddSibling("fuga-3", "Fuga 3")
.UpToParent("games")
.Add("cyberpunk", "Cyberpunk 2077")
.AddSibling("elden-ring", "Elden Ring")
.Build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
title: TrailMenu
icon: Menu
route: /TrailMenu
---

# TrailMenu

The TrailMenu component is a menu that can be used to display a list of items. It's like a breadcrumb,
but it's more like Windows 11 breadcrumbs, with separators act like a menu, and the items are displayed in a horizontal line. The TrailMenu component is useful when you want to display a list of items that are related to each other, and you want to allow the user to navigate through them.
## Examples



{{ RootAndPathExample }}


## API Resizer

{{ API Type=TrailMenu }}
{{ API Type=TrailMenuButton }}
76 changes: 76 additions & 0 deletions src/Core/Components/Base/TrailMenu/TrailMenuCache.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
namespace FluentUI.Blazor.Community.Components.TrailMenu;

/// <summary>
/// Provides a cache for storing and managing size values associated with unique trail menu identifiers.
/// </summary>
/// <remarks>TrailMenuCache enables efficient retrieval, updating, and invalidation of size values for trail menu
/// items. The cache supports calculating the total size of all tracked items and allows selective clearing of entries
/// by identifier. This class is intended for internal use and is not thread-safe.</remarks>
internal sealed class TrailMenuCache
{
/// <summary>
/// Stores size values mapped to their corresponding string keys.
/// </summary>
/// <remarks>This dictionary is initialized as empty and can be populated with key-value pairs
/// representing sizes. It is typically used to associate specific size measurements with unique
/// identifiers.</remarks>
private readonly Dictionary<string, double> _sizes = [];

/// <summary>
/// Gets the total size calculated by summing all values in the sizes collection.
/// </summary>
/// <remarks>This property provides a quick way to retrieve the cumulative size without needing to iterate
/// through the collection manually. It reflects the current state of the sizes collection and updates automatically
/// as values change.</remarks>
public double TotalSize => _sizes.Values.Sum();

/// <summary>
/// Attempts to retrieve the size associated with the specified identifier.
/// </summary>
/// <remarks>This method is useful for safely attempting to get a value without throwing an exception if
/// the identifier does not exist.</remarks>
/// <param name="id">The unique identifier for which the size is to be retrieved. This parameter cannot be null or empty.</param>
/// <param name="size">When this method returns <see langword="true"/>, this output parameter contains the size associated with the
/// specified identifier; otherwise, it is set to zero.</param>
/// <returns><see langword="true"/> if the size was successfully retrieved; otherwise, <see langword="false"/>.</returns>
public bool TryGet(string id, out double size) => _sizes.TryGetValue(id, out size);

/// <summary>
/// Associates the specified size value with the given identifier.
/// </summary>
/// <remarks>If the identifier already exists, its associated size will be updated to the new
/// value.</remarks>
/// <param name="id">The unique identifier for which the size is being set. This value cannot be null or empty.</param>
/// <param name="size">The size value to associate with the specified identifier. Must be a non-negative number.</param>
public void Set(string id, double size) => _sizes[id] = size;

/// <summary>
/// Invalidates the size associated with the specified identifier by resetting it to zero.
/// </summary>
/// <remarks>If the specified identifier does not exist in the sizes dictionary, no action is
/// taken.</remarks>
/// <param name="id">The unique identifier for which the size should be invalidated. This parameter must not be null and must
/// correspond to an existing entry in the sizes dictionary.</param>
public void Invalidate(string id)
{
if (_sizes.ContainsKey(id))
{
_sizes[id] = 0;
}
}

/// <summary>
/// Removes the specified identifiers from the collection, ignoring any null or empty values.
/// </summary>
/// <remarks>This method modifies the internal collection by removing entries corresponding to the
/// provided identifiers. It is important to ensure that the identifiers are valid and exist in the collection to
/// avoid unnecessary operations.</remarks>
/// <param name="ids">An enumerable collection of identifiers to be removed. Only non-null and non-empty identifiers are processed.</param>
public void Clear(IEnumerable<string?> ids)
{
foreach (var id in ids.Where(x => !string.IsNullOrEmpty(x)))
{
_sizes.Remove(id!);
}
}
}
Loading