From 4168a88de7633da7e5e6bafef66b34362911e77a Mon Sep 17 00:00:00 2001 From: Saleh Yusefnejad Date: Sun, 4 Jan 2026 22:49:01 +0330 Subject: [PATCH 1/6] add BitIconInfo #11684 --- .../Bit.BlazorUI/Components/BitIconInfo.cs | 218 +++++++++++ .../Utilities/Icon/BitIcon.razor.cs | 20 +- .../Utilities/Icon/BitIconDemo.razor | 69 ++-- .../Utilities/Icon/BitIconDemo.razor.cs | 43 ++- .../Utilities/Icon/BitIconInfoTests.cs | 355 ++++++++++++++++++ 5 files changed, 663 insertions(+), 42 deletions(-) create mode 100644 src/BlazorUI/Bit.BlazorUI/Components/BitIconInfo.cs create mode 100644 src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Utilities/Icon/BitIconInfoTests.cs diff --git a/src/BlazorUI/Bit.BlazorUI/Components/BitIconInfo.cs b/src/BlazorUI/Bit.BlazorUI/Components/BitIconInfo.cs new file mode 100644 index 0000000000..d5f2b8724d --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI/Components/BitIconInfo.cs @@ -0,0 +1,218 @@ +namespace Bit.BlazorUI; + +/// +/// Represents icon information for rendering icons in Bit BlazorUI components. +/// Supports both built-in Fluent UI icons and custom/external icon libraries. +/// +public class BitIconInfo +{ + /// + /// Creates a new instance of . + /// + public BitIconInfo() { } + + /// + /// Creates a new instance of with the specified icon name. + /// + /// The name of the icon. For built-in icons, use values from BitIconName. + public BitIconInfo(string name) + { + Name = name; + } + + /// + /// Creates a new instance of with full customization. + /// + /// The name of the icon or the CSS class for external icons. + /// + /// The base CSS class for the icon. + /// Set to empty string for external icon libraries that don't need a base class. + /// When null, defaults to "bit-icon" for built-in icons. + /// + /// + /// The CSS class prefix used before the icon name. + /// When null, defaults to "bit-icon--" for built-in icons. + /// Set to empty string for external icons that don't use a prefix. + /// + public BitIconInfo(string name, string? baseClass, string? prefix = null) + { + Name = name; + BaseClass = baseClass; + Prefix = prefix; + } + + /// + /// Gets or sets the name of the icon. + /// For built-in icons, use values from BitIconName (e.g., "Add", "Delete"). + /// For external icons, this can be the full CSS class name if and are empty. + /// + public string? Name { get; set; } + + /// + /// Gets or sets the base CSS class for the icon. + /// For built-in Fluent UI icons, this defaults to "bit-icon". + /// For external icon libraries like FontAwesome, you might set this to "fa" or leave empty. + /// + /// + /// For FontAwesome: BaseClass = "fa" or BaseClass = "" + /// For Material Icons: BaseClass = "material-icons" or BaseClass = "" + /// + public string? BaseClass { get; set; } + + /// + /// Gets or sets the CSS class prefix used before the icon name. + /// For built-in Fluent UI icons, this defaults to "bit-icon--". + /// For external icon libraries, you might set this to "fa-" or leave empty. + /// + /// + /// For FontAwesome 6: Prefix = "" and Name = "fa-solid fa-house" + /// For FontAwesome 5: Prefix = "fa-" and Name = "house" + /// + public string? Prefix { get; set; } + + /// + /// Determines whether the icon has a valid name set. + /// + /// true if the icon has a non-empty name; otherwise, false. + public bool HasValue() => Name.HasValue(); + + /// + /// Gets the CSS classes to render the icon. + /// + /// The complete CSS class string for the icon. + public string GetCssClasses() + { + if (Name.HasNoValue()) return string.Empty; + + if (BaseClass.HasNoValue() && Prefix.HasNoValue()) + { + return Name!; + } + + if (BaseClass.HasNoValue()) + { + return $"{Prefix}{Name}"; + } + + if (Prefix.HasNoValue()) + { + return $"{BaseClass} {Name}"; + } + + return $"{BaseClass} {Prefix}{Name}"; + } + + /// + /// Implicit conversion from string to . + /// This maintains backward compatibility with the existing string-based IconName parameter. + /// + /// The icon name string. + public static implicit operator BitIconInfo?(string? iconName) + { + if (iconName is null) return null; + + return new BitIconInfo(iconName); + } + + /// + /// Implicit conversion from to string. + /// Returns the icon name for simple scenarios. + /// + /// The icon info instance. + public static implicit operator string?(BitIconInfo? iconInfo) + { + return iconInfo?.Name; + } + + /// + /// Creates a for an external/custom icon using the provided CSS classes directly. + /// + /// The complete CSS class(es) to render the icon (e.g., "fa-solid fa-house" for FontAwesome 6). + /// A new instance configured for external icons. + /// + /// FontAwesome 6: BitIconInfo.Css("fa-solid fa-house") + /// Material Icons: BitIconInfo.Css("material-icons home") + /// Bootstrap Icons: BitIconInfo.Css("bi bi-house") + /// + public static BitIconInfo Css(string cssClasses) + { + return new BitIconInfo(cssClasses, baseClass: "", prefix: ""); + } + + /// + /// Creates a for a built-in bit BlazorUI icon. + /// + /// The bit BlazorUI icon name (e.g., "add"). + /// A new instance configured for bit BlazorUI icons. + /// + /// BitIconInfo.Bit("add") + /// + public static BitIconInfo Bit(string name) + { + return new BitIconInfo(name, baseClass: "bit-icon", prefix: "bit-icon--"); + } + + /// + /// Creates a for a FontAwesome icon. + /// + /// The FontAwesome icon classes (e.g., "fa-solid fa-house" or just "fa-house" with style parameter). + /// A new instance configured for FontAwesome icons. + /// + /// BitIconInfo.Fa("solid house") + /// BitIconInfo.Fa("fa-brands fa-github") + /// + public static BitIconInfo Fa(string icons) + { + var cssClasses = string.Join(' ', icons.Split(' ').Select(i => i.StartsWith("fa-") ? i : $"fa-{i}")); + + return new BitIconInfo(cssClasses, baseClass: "", prefix: ""); + } + + /// + /// Creates a for a Material Icons icon. + /// + /// The Material Icon name (e.g., "home", "search", "menu"). + /// A new instance configured for Material Icons. + /// + /// BitIconInfo.Material("home") + /// BitIconInfo.Material("search") + /// + public static BitIconInfo Material(string iconName) + { + return new BitIconInfo(iconName, baseClass: "material-icons", prefix: ""); + } + + /// + /// Creates a for a Bootstrap Icons icon. + /// + /// The Bootstrap Icon name without the "bi-" prefix (e.g., "house", "search"). + /// A new instance configured for Bootstrap Icons. + /// + /// BitIconInfo.Bootstrap("house") + /// BitIconInfo.Bootstrap("search") + /// + public static BitIconInfo Bootstrap(string iconName) + { + return new BitIconInfo(iconName, baseClass: "bi", prefix: "bi-"); + } + + /// + /// Resolves the effective icon from either a or an icon name string. + /// The parameter takes precedence when both are provided. + /// + /// The icon info instance, if provided. + /// The icon name string for built-in icons, if provided. + /// A instance if either parameter has a value; otherwise, null. + /// + /// This method is intended for internal use by components to unify the handling of + /// the Icon and IconName parameters. + /// + public static BitIconInfo? From(BitIconInfo? icon, string? iconName) + { + if (icon is not null) return icon; + + if (iconName.HasNoValue()) return null; + + return Bit(iconName!); + } +} diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Utilities/Icon/BitIcon.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Utilities/Icon/BitIcon.razor.cs index 9d9d7846d5..50c234d7e4 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Utilities/Icon/BitIcon.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Utilities/Icon/BitIcon.razor.cs @@ -12,11 +12,27 @@ public partial class BitIcon : BitComponentBase public BitColor? Color { get; set; } /// - /// The icon name for the icon shown. + /// The icon name for the icon shown from the built-in Fluent UI icons. /// [Parameter, ResetClassBuilder] public string? IconName { get; set; } + /// + /// The icon to display using custom CSS classes for external icon libraries. + /// Takes precedence over when both are set. + /// + /// + /// Use this property to render icons from external libraries like FontAwesome, Material Icons, or Bootstrap Icons. + /// For built-in Fluent UI icons, use instead. + /// + /// + /// FontAwesome: Icon="BitIconInfo.Fa("solid house")" + /// Material: Icon="BitIconInfo.Material("home")" + /// Custom CSS: Icon="BitIconInfo.Css("my-icon-class")" + /// + [Parameter, ResetClassBuilder] + public BitIconInfo? Icon { get; set; } + /// /// The size of the icon. /// @@ -57,7 +73,7 @@ protected override void RegisterCssClasses() _ => "bit-ico-pri" }); - ClassBuilder.Register(() => IconName.HasValue() ? $"bit-icon bit-icon--{IconName}" : string.Empty); + ClassBuilder.Register(() => BitIconInfo.From(Icon, IconName)?.GetCssClasses()); ClassBuilder.Register(() => Size switch { diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Utilities/Icon/BitIconDemo.razor b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Utilities/Icon/BitIconDemo.razor index f4829557b9..0b918d2421 100644 --- a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Utilities/Icon/BitIconDemo.razor +++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Utilities/Icon/BitIconDemo.razor @@ -1,4 +1,4 @@ -@page "/components/icon" +@page "/components/icon" - -
Small

- -   - -   - -



-
Medium

- -   - -   - -



-
Large

- -   - -   - -
- - +
Offering a range of specialized color variants, providing visual cues for specific actions or states within your application.



Primary

@@ -119,7 +96,47 @@
- + +
Use icons from external libraries like FontAwesome with the Icon parameter.
+ +
+
+ + + + +   + +   + +   + +
+ + +
Small

+ +   + +   + +



+
Medium

+ +   + +   + +



+
Large

+ +   + +   + +
+ +
diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Utilities/Icon/BitIconDemo.razor.cs b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Utilities/Icon/BitIconDemo.razor.cs index 28f1cedbab..dcbd599dfc 100644 --- a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Utilities/Icon/BitIconDemo.razor.cs +++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Utilities/Icon/BitIconDemo.razor.cs @@ -14,11 +14,18 @@ public partial class BitIconDemo Href = "#color-enum", }, new() + { + Name = "Icon", + Type = "BitIconInfo?", + DefaultValue = "null", + Description = "The icon to display using custom CSS classes for external icon libraries. Takes precedence over IconName when both are set.", + }, + new() { Name = "IconName", Type = "string", DefaultValue = "", - Description = "The icon name for the icon shown", + Description = "The icon name for the icon shown from built-in Fluent UI icons.", LinkType = LinkType.Link, Href = "/iconography", }, @@ -230,19 +237,6 @@ public partial class BitIconDemo "; private readonly string example3RazorCode = @" - - - - - - - - - - -"; - - private readonly string example4RazorCode = @" @@ -275,7 +269,28 @@ public partial class BitIconDemo "; + private readonly string example4RazorCode = @" + + + + + +"; + private readonly string example5RazorCode = @" + + + + + + + + + + +"; + + private readonly string example6RazorCode = @" - -"; + +"; } diff --git a/src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Utilities/Icon/BitIconInfoTests.cs b/src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Utilities/Icon/BitIconInfoTests.cs index 8b3d4b9ae0..ecb17a6cf4 100644 --- a/src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Utilities/Icon/BitIconInfoTests.cs +++ b/src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Utilities/Icon/BitIconInfoTests.cs @@ -98,31 +98,10 @@ public void FontAwesomeShouldHandleBrandIcons() Assert.AreEqual("fa-brands fa-github", iconInfo.GetCssClasses()); } - [TestMethod] - public void MaterialShouldCreateMaterialIconInfo() - { - var iconInfo = BitIconInfo.Material("home"); - - Assert.AreEqual("home", iconInfo.Name); - Assert.AreEqual("material-icons", iconInfo.BaseClass); - Assert.AreEqual("", iconInfo.Prefix); - Assert.AreEqual("material-icons home", iconInfo.GetCssClasses()); - } - - [TestMethod] - public void MaterialShouldHandleVariousIconNames() - { - var iconInfo = BitIconInfo.Material("settings"); - - Assert.AreEqual("settings", iconInfo.Name); - Assert.AreEqual("material-icons", iconInfo.BaseClass); - Assert.AreEqual("material-icons settings", iconInfo.GetCssClasses()); - } - [TestMethod] public void BootstrapShouldCreateBootstrapIconInfo() { - var iconInfo = BitIconInfo.Bootstrap("check-circle"); + var iconInfo = BitIconInfo.Bi("check-circle"); Assert.AreEqual("check-circle", iconInfo.Name); Assert.AreEqual("bi", iconInfo.BaseClass); @@ -133,7 +112,7 @@ public void BootstrapShouldCreateBootstrapIconInfo() [TestMethod] public void BootstrapShouldHandleVariousIconNames() { - var iconInfo = BitIconInfo.Bootstrap("house"); + var iconInfo = BitIconInfo.Bi("house"); Assert.AreEqual("house", iconInfo.Name); Assert.AreEqual("bi", iconInfo.BaseClass); @@ -211,19 +190,11 @@ public void GetCssClassesFontAwesome6BrandIconShouldGenerateCorrectClasses() [TestMethod] public void GetCssClassesBootstrapShouldGenerateCorrectClasses() { - var iconInfo = BitIconInfo.Bootstrap("arrow-right"); + var iconInfo = BitIconInfo.Bi("arrow-right"); Assert.AreEqual("bi bi-arrow-right", iconInfo.GetCssClasses()); } - [TestMethod] - public void GetCssClassesMaterialShouldGenerateCorrectClasses() - { - var iconInfo = BitIconInfo.Material("favorite"); - - Assert.AreEqual("material-icons favorite", iconInfo.GetCssClasses()); - } - [TestMethod] public void GetCssClassesCustomCssShouldGenerateCorrectClasses() { @@ -283,7 +254,7 @@ public void GetCssClassesWithSpecialCharactersInNameShouldHandleCorrectly() [TestMethod] public void GetCssClassesBootstrapWithHyphenatedNameShouldHandleCorrectly() { - var iconInfo = BitIconInfo.Bootstrap("check-circle-fill"); + var iconInfo = BitIconInfo.Bi("check-circle-fill"); Assert.AreEqual("bi bi-check-circle-fill", iconInfo.GetCssClasses()); } From c5dee626b716ee98ad7f3fa04d9f242c425cfda2 Mon Sep 17 00:00:00 2001 From: Saleh Yusefnejad Date: Mon, 5 Jan 2026 00:24:11 +0330 Subject: [PATCH 5/6] improve demo docs --- .../Utilities/Icon/BitIconDemo.razor | 1 + .../Utilities/Icon/BitIconDemo.razor.cs | 35 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Utilities/Icon/BitIconDemo.razor b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Utilities/Icon/BitIconDemo.razor index 9a930c399f..f834edbba0 100644 --- a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Utilities/Icon/BitIconDemo.razor +++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Utilities/Icon/BitIconDemo.razor @@ -7,6 +7,7 @@ diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Utilities/Icon/BitIconDemo.razor.cs b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Utilities/Icon/BitIconDemo.razor.cs index a4e3cfd16a..fa28a82786 100644 --- a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Utilities/Icon/BitIconDemo.razor.cs +++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Utilities/Icon/BitIconDemo.razor.cs @@ -19,6 +19,8 @@ public partial class BitIconDemo Type = "BitIconInfo?", DefaultValue = "null", Description = "Specifies the icon configuration for rendering icons from external icon libraries using custom CSS classes. Takes precedence over IconName when both are set.", + LinkType = LinkType.Link, + Href = "#bit-icon-info", }, new() { @@ -49,6 +51,39 @@ public partial class BitIconDemo }, ]; + private readonly List componentSubClasses = + [ + new() + { + Id = "bit-icon-info", + Title = "BitIconInfo", + Parameters = + [ + new() + { + Name = "Name", + Type = "string?", + DefaultValue = "null", + Description = "Gets or sets the name of the icon." + }, + new() + { + Name = "BaseClass", + Type = "string?", + DefaultValue = "null", + Description = "Gets or sets the base CSS class for the icon. For built-in Fluent UI icons, this defaults to \"bit-icon\". For external icon libraries like FontAwesome, you might set this to \"fa\" or leave empty." + }, + new() + { + Name = "Prefix", + Type = "string?", + DefaultValue = "null", + Description = "Gets or sets the CSS class prefix used before the icon name. For built-in Fluent UI icons, this defaults to \"bit-icon--\". For external icon libraries, you might set this to \"fa-\" or leave empty." + }, + ] + }, + ]; + private readonly List componentSubEnums = [ new() From b9d29eb976854b4e75ffcd12a3d2778df0af56e5 Mon Sep 17 00:00:00 2001 From: msynk Date: Mon, 5 Jan 2026 13:26:47 +0330 Subject: [PATCH 6/6] resolve review comments --- .../Bit.BlazorUI/Components/BitIconInfo.cs | 7 +- .../Utilities/Icon/BitIconInfoTests.cs | 145 ++++++++++++++++++ 2 files changed, 149 insertions(+), 3 deletions(-) diff --git a/src/BlazorUI/Bit.BlazorUI/Components/BitIconInfo.cs b/src/BlazorUI/Bit.BlazorUI/Components/BitIconInfo.cs index 84409d2c6f..7558101df7 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/BitIconInfo.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/BitIconInfo.cs @@ -154,7 +154,8 @@ public static BitIconInfo Bit(string name) /// public static BitIconInfo Fa(string icons) { - var cssClasses = string.Join(' ', icons.Split(' ').Select(i => i.StartsWith("fa-") ? i : $"fa-{i}")); + var cssClasses = string.Join(' ', icons.Split(' ', StringSplitOptions.RemoveEmptyEntries) + .Select(i => i.StartsWith("fa-") ? i : $"fa-{i}")); return new BitIconInfo(cssClasses, baseClass: "", prefix: ""); } @@ -187,10 +188,10 @@ public static BitIconInfo Bi(string iconName) /// A instance if either parameter has a value; otherwise, null. /// /// - /// This method is intended for internal use by components to unify the handling of + /// This method is useful for components to unify the handling of /// the Icon and IconName parameters. /// - internal static BitIconInfo? From(BitIconInfo? icon, string? iconName) + public static BitIconInfo? From(BitIconInfo? icon, string? iconName) { if (icon is not null) return icon; diff --git a/src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Utilities/Icon/BitIconInfoTests.cs b/src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Utilities/Icon/BitIconInfoTests.cs index ecb17a6cf4..d391926a64 100644 --- a/src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Utilities/Icon/BitIconInfoTests.cs +++ b/src/BlazorUI/Tests/Bit.BlazorUI.Tests/Components/Utilities/Icon/BitIconInfoTests.cs @@ -278,4 +278,149 @@ public void GetCssClassesWithNullNameShouldReturnEmptyString() Assert.AreEqual("", result); } + + // Bit Factory Method Tests + + [TestMethod] + public void BitShouldCreateIconInfoForBitBlazorUIIcons() + { + var iconInfo = BitIconInfo.Bit("Add"); + + Assert.AreEqual("Add", iconInfo.Name); + Assert.AreEqual("bit-icon", iconInfo.BaseClass); + Assert.AreEqual("bit-icon--", iconInfo.Prefix); + Assert.AreEqual("bit-icon bit-icon--Add", iconInfo.GetCssClasses()); + } + + [TestMethod] + public void BitShouldHandleVariousIconNames() + { + var iconInfo = BitIconInfo.Bit("ChevronDown"); + + Assert.AreEqual("ChevronDown", iconInfo.Name); + Assert.AreEqual("bit-icon", iconInfo.BaseClass); + Assert.AreEqual("bit-icon--", iconInfo.Prefix); + Assert.AreEqual("bit-icon bit-icon--ChevronDown", iconInfo.GetCssClasses()); + } + + // From Method Tests + + [TestMethod] + public void FromShouldReturnIconWhenIconIsProvided() + { + var icon = BitIconInfo.Fa("fa-solid fa-home"); + + var result = BitIconInfo.From(icon, "Add"); + + Assert.AreSame(icon, result); + } + + [TestMethod] + public void FromShouldCreateBitIconWhenOnlyIconNameIsProvided() + { + var result = BitIconInfo.From(null, "Add"); + + Assert.IsNotNull(result); + Assert.AreEqual("Add", result.Name); + Assert.AreEqual("bit-icon", result.BaseClass); + Assert.AreEqual("bit-icon--", result.Prefix); + Assert.AreEqual("bit-icon bit-icon--Add", result.GetCssClasses()); + } + + [TestMethod] + public void FromShouldReturnNullWhenBothParametersAreNull() + { + var result = BitIconInfo.From(null, null); + + Assert.IsNull(result); + } + + [TestMethod] + public void FromShouldReturnNullWhenIconNameIsEmpty() + { + var result = BitIconInfo.From(null, ""); + + Assert.IsNull(result); + } + + [TestMethod] + public void FromShouldPrioritizeIconOverIconName() + { + var icon = BitIconInfo.Bi("house"); + + var result = BitIconInfo.From(icon, "Add"); + + Assert.AreSame(icon, result); + Assert.AreEqual("bi bi-house", result?.GetCssClasses()); + } + + // Null BaseClass and Prefix Tests + + [TestMethod] + public void GetCssClassesWithNullBaseClassAndNullPrefixShouldReturnNameOnly() + { + var iconInfo = new BitIconInfo("home"); + + var result = iconInfo.GetCssClasses(); + + Assert.AreEqual("home", result); + } + + [TestMethod] + public void GetCssClassesWithNullBaseClassAndPrefixShouldReturnPrefixedName() + { + var iconInfo = new BitIconInfo("home", null, "icon-"); + + var result = iconInfo.GetCssClasses(); + + Assert.AreEqual("icon-home", result); + } + + [TestMethod] + public void GetCssClassesWithBaseClassAndNullPrefixShouldReturnBaseClassAndName() + { + var iconInfo = new BitIconInfo("home", "material-icons", null); + + var result = iconInfo.GetCssClasses(); + + Assert.AreEqual("material-icons home", result); + } + + // FontAwesome Shorthand Tests + + [TestMethod] + public void FontAwesomeShouldAddFaPrefixWhenMissing() + { + var iconInfo = BitIconInfo.Fa("solid home"); + + Assert.AreEqual("fa-solid fa-home", iconInfo.Name); + Assert.AreEqual("fa-solid fa-home", iconInfo.GetCssClasses()); + } + + [TestMethod] + public void FontAwesomeShouldNotAddFaPrefixWhenAlreadyPresent() + { + var iconInfo = BitIconInfo.Fa("fa-solid fa-home"); + + Assert.AreEqual("fa-solid fa-home", iconInfo.Name); + Assert.AreEqual("fa-solid fa-home", iconInfo.GetCssClasses()); + } + + [TestMethod] + public void FontAwesomeShouldHandleMixedPrefixes() + { + var iconInfo = BitIconInfo.Fa("fa-solid home"); + + Assert.AreEqual("fa-solid fa-home", iconInfo.Name); + Assert.AreEqual("fa-solid fa-home", iconInfo.GetCssClasses()); + } + + [TestMethod] + public void FontAwesomeShouldHandleExtraSpaces() + { + var iconInfo = BitIconInfo.Fa(" solid home "); + + Assert.AreEqual("fa-solid fa-home", iconInfo.Name); + Assert.AreEqual("fa-solid fa-home", iconInfo.GetCssClasses()); + } }