Skip to content

Commit

Permalink
[Icons and Emojis] Update AllIcons and AllEmojis extension methods (
Browse files Browse the repository at this point in the history
#3026)

* Fix the Extension methods

* Update the Explorers
  • Loading branch information
dvoituron authored Dec 6, 2024
1 parent 9349aac commit acc842f
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ private string FullName

if (Emoji != null)
{
return $"{Emoji.Group}.{Emoji.Style}.{Emoji.Skintone}.{Emoji.Name}";
return $"{Emoji.Group}.{Emoji.Style}.{Emoji.Skintone}.{Emoji.Name}".Replace("_", "");
}

return string.Empty;
Expand All @@ -51,7 +51,7 @@ public async void CopyToClipboardAsync()
if (Icon != null)
{
// Icons.[IconVariant].[IconSize].[IconName]
var value = $"Value=\"@(new Icons.{FullName}())\"";
var value = $"Value=\"@(new Microsoft.FluentUI.AspNetCore.Components.Icons.{FullName}())\"";
var color = IconColor == Color.Accent ? string.Empty : $" Color=\"@Color.{IconColor}\"";

var code = $"<FluentIcon {value}{color} />";
Expand All @@ -72,7 +72,7 @@ public async void CopyToClipboardAsync()
if (Emoji != null)
{
// Emojis.[EmojiGroup].[EmojiStyle].[EmojiSkintone].[EmojiName]
var value = $"Value=\"@(new Emojis.{FullName}())\"";
var value = $"Value=\"@(new Microsoft.FluentUI.AspNetCore.Components.Emojis.{FullName}())\"";

var code = $"<FluentEmoji {value} />";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ private async Task StartNewSearchAsync()
EmojisFound =
[
.. EmojiExtensions.AllEmojis
.Where(i => i.Style == Criteria.Style
&& (string.IsNullOrWhiteSpace(Criteria.SearchTerm) ? true : i.Name.Contains(Criteria.SearchTerm, StringComparison.InvariantCultureIgnoreCase)))
.OrderBy(i => i.Name)
.Where(i => i.Style == Criteria.Style
&& (string.IsNullOrWhiteSpace(Criteria.SearchTerm) ? true : i.Name.Contains(Criteria.SearchTerm, StringComparison.InvariantCultureIgnoreCase)))
.OrderBy(i => i.Name)
,
];

Expand Down
56 changes: 39 additions & 17 deletions src/Core/Components/Emojis/EmojiExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,40 @@
// ------------------------------------------------------------------------

using System.Diagnostics.CodeAnalysis;
using System.Reflection;

namespace Microsoft.FluentUI.AspNetCore.Components;

/// <summary />
public static partial class EmojiExtensions
{
private const string Namespace = "Microsoft.FluentUI.AspNetCore.Components";
private const string LibraryName = "Microsoft.FluentUI.AspNetCore.Components.Emojis";
private const string LibraryName = "Microsoft.FluentUI.AspNetCore.Components.Emojis.{0}"; // {0} must be replaced with the "Group": SmileysEmotion, PeopleBody, etc.

/// <summary>
/// Returns a new instance of the emoji.
/// </summary>
/// <remarks>
/// This method requires dynamic access to code. This code may be removed by the trimmer.
/// If the assembly is not yet loaded, it will be loaded by the method `Assembly.Load`.
/// To avoid any issues, the assembly must be loaded before calling this method (e.g. adding an emoji in your code).
/// </remarks>
/// <returns></returns>
/// <exception cref="ArgumentException">Raised when the <see cref="EmojiInfo.Name"/> is not found in predefined emojis.</exception>
[RequiresUnreferencedCode("This method requires dynamic access to code. This code may be removed by the trimmer.")]
public static CustomEmoji GetInstance(this EmojiInfo emoji)
{
var assembly = AppDomain.CurrentDomain
.GetAssemblies()
.FirstOrDefault(i => i.ManifestModule.Name.StartsWith(LibraryName, StringComparison.Ordinal));
var group = emoji.Group.ToString().Replace("_", string.Empty);
var assemblyName = string.Format(LibraryName, group);
var assembly = GetAssembly(assemblyName);

if (assembly != null)
{
var allEmojis = assembly.GetTypes()
.Where(i => i.BaseType == typeof(Emoji));

// Ex. Microsoft.FluentUI.AspNetCore.Components.Emojis+Activities+Color+Default+Baseball
var group = emoji.Group.ToString().Replace("_", string.Empty);
var emojiFullName = $"{Namespace}.Emojis+{group}+{emoji.Style}+{emoji.Skintone}+{emoji.Name}";
// Ex. Microsoft.FluentUI.AspNetCore.Components.Emojis.Activities.Color.Default+Baseball
var emojiFullName = $"{Namespace}.Emojis.{group}.{emoji.Style}.{emoji.Skintone}+{emoji.Name}";
var emojiType = allEmojis.FirstOrDefault(i => i.FullName == emojiFullName);

if (emojiType != null)
Expand All @@ -47,7 +49,7 @@ public static CustomEmoji GetInstance(this EmojiInfo emoji)
}
}

throw new ArgumentException($"Emoji '{emoji.Name}' not found.");
throw new ArgumentException($"Emoji 'Emojis.{group}.{emoji.Style}.{emoji.Skintone}.{emoji.Name}' not found.");
}

/// <summary>
Expand All @@ -61,21 +63,24 @@ public static CustomEmoji GetInstance(this EmojiInfo emoji)
[RequiresUnreferencedCode("This method requires dynamic access to code. This code may be removed by the trimmer.")]
public static IEnumerable<EmojiInfo> GetAllEmojis()
{
var assembly = AppDomain.CurrentDomain
.GetAssemblies()
.FirstOrDefault(i => i.ManifestModule.Name.StartsWith(LibraryName, StringComparison.Ordinal));
var allIcons = new List<EmojiInfo>();

if (assembly != null)
foreach (var group in Enum.GetValues(typeof(EmojiGroup)).Cast<EmojiGroup>())
{
var allTypes = assembly.GetTypes()
.Where(i => i.BaseType == typeof(Emoji));
var assemblyName = string.Format(LibraryName, group.ToString().Replace("_", string.Empty));
var assembly = GetAssembly(assemblyName);

var allEmojis = allTypes.Select(type => Activator.CreateInstance(type) as EmojiInfo ?? new EmojiInfo());
if (assembly != null)
{
var allTypes = assembly.GetTypes()
.Where(i => i.BaseType == typeof(Emoji)
&& i.Name != nameof(CustomEmoji));

return allEmojis ?? Array.Empty<EmojiInfo>();
allIcons.AddRange(allTypes.Select(type => Activator.CreateInstance(type) as EmojiInfo ?? new EmojiInfo()));
}
}

return Array.Empty<EmojiInfo>();
return allIcons;
}

/// <summary />
Expand All @@ -86,4 +91,21 @@ public static IEnumerable<EmojiInfo> AllEmojis
return GetAllEmojis();
}
}

/// <summary />
private static Assembly? GetAssembly(string assemblyName)
{
try
{
return AppDomain.CurrentDomain
.GetAssemblies()
.FirstOrDefault(i => i.ManifestModule.Name == assemblyName + ".dll")
?? Assembly.Load(assemblyName);

}
catch (Exception)
{
return null;
}
}
}
53 changes: 37 additions & 16 deletions src/Core/Components/Icons/IconsExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,39 @@
// ------------------------------------------------------------------------

using System.Diagnostics.CodeAnalysis;
using System.Reflection;

namespace Microsoft.FluentUI.AspNetCore.Components;

/// <summary />
public static partial class IconsExtensions
{
private const string Namespace = "Microsoft.FluentUI.AspNetCore.Components";
private const string LibraryName = "Microsoft.FluentUI.AspNetCore.Components.Icons";
private const string LibraryName = "Microsoft.FluentUI.AspNetCore.Components.Icons.{0}"; // {0} must be replaced with the "Variant": Regular, Filled, etc.

/// <summary>
/// Returns a new instance of the icon.
/// </summary>
/// <param name="icon">The <see cref="IconInfo"/> to instantiate.</param>
/// <remarks>
/// This method requires dynamic access to code. This code may be removed by the trimmer.
/// If the assembly is not yet loaded, it will be loaded by the method `Assembly.Load`.
/// To avoid any issues, the assembly must be loaded before calling this method (e.g. adding an icon in your code).
/// </remarks>
/// <returns></returns>
/// <exception cref="ArgumentException">Raised when the <see cref="IconInfo.Name"/> is not found in predefined icons.</exception>
[RequiresUnreferencedCode("This method requires dynamic access to code. This code may be removed by the trimmer.")]
public static CustomIcon GetInstance(this IconInfo icon)
{
var assembly = AppDomain.CurrentDomain
.GetAssemblies()
.FirstOrDefault(i => i.ManifestModule.Name.StartsWith(LibraryName, StringComparison.Ordinal));
var assemblyName = string.Format(LibraryName, icon.Variant);
var assembly = GetAssembly(assemblyName);

if (assembly != null)
{
var allIcons = assembly.GetTypes()
.Where(i => i.BaseType == typeof(Icon));

// Ex. Microsoft.FluentUI.AspNetCore.Components.Icons+Filled+Size10+PresenceAvailable
// Ex. Microsoft.FluentUI.AspNetCore.Components.Icons.Filled.Size10+PresenceAvailable
var iconFullName = $"{Namespace}.Icons.{icon.Variant}.Size{(int)icon.Size}+{icon.Name}";
var iconType = allIcons.FirstOrDefault(i => i.FullName == iconFullName);

Expand All @@ -47,7 +49,7 @@ public static CustomIcon GetInstance(this IconInfo icon)
}
}

throw new ArgumentException($"Icon '{icon.Name}' not found.");
throw new ArgumentException($"Icon 'Icons.{icon.Variant}.Size{(int)icon.Size}.{icon.Name}' not found.");
}

/// <summary>
Expand All @@ -61,22 +63,24 @@ public static CustomIcon GetInstance(this IconInfo icon)
[RequiresUnreferencedCode("This method requires dynamic access to code. This code may be removed by the trimmer.")]
public static IEnumerable<IconInfo> GetAllIcons()
{
var assembly = AppDomain.CurrentDomain
.GetAssemblies()
.FirstOrDefault(i => i.ManifestModule.Name.StartsWith(LibraryName, StringComparison.Ordinal));
var allIcons = new List<IconInfo>();

if (assembly != null)
foreach (var variant in Enum.GetValues(typeof(IconVariant)).Cast<IconVariant>())
{
var allTypes = assembly.GetTypes()
.Where(i => i.BaseType == typeof(Icon)
&& i.Name != nameof(CustomIcon));
var assemblyName = string.Format(LibraryName, variant);
var assembly = GetAssembly(assemblyName);

var allIcons = allTypes.Select(type => Activator.CreateInstance(type) as IconInfo ?? new IconInfo());
if (assembly != null)
{
var allTypes = assembly.GetTypes()
.Where(i => i.BaseType == typeof(Icon)
&& i.Name != nameof(CustomIcon));

return allIcons ?? [];
allIcons.AddRange(allTypes.Select(type => Activator.CreateInstance(type) as IconInfo ?? new IconInfo()));
}
}

return [];
return allIcons;
}

/// <summary />
Expand All @@ -87,4 +91,21 @@ public static IEnumerable<IconInfo> AllIcons
return GetAllIcons();
}
}

/// <summary />
private static Assembly? GetAssembly(string assemblyName)
{
try
{
return AppDomain.CurrentDomain
.GetAssemblies()
.FirstOrDefault(i => i.ManifestModule.Name == assemblyName + ".dll")
?? Assembly.Load(assemblyName);

}
catch (Exception)
{
return null;
}
}
}

0 comments on commit acc842f

Please sign in to comment.