diff --git a/Lombiq.HelpfulExtensions/Extensions/SimpleIcons/Readme.md b/Lombiq.HelpfulExtensions/Extensions/SimpleIcons/Readme.md new file mode 100644 index 00000000..c01ca99a --- /dev/null +++ b/Lombiq.HelpfulExtensions/Extensions/SimpleIcons/Readme.md @@ -0,0 +1,20 @@ +# Simple Icons + +Adds [Simple Icons](https://simpleicons.org/) icon library integration. All icons are directly available in the _~/Lombiq.HelpfulExtensions/vendors/simple-icons/icons/*.svg_ location. + +## Shape and Tag Helper + +You can display the icon in a more structured manner using the `SimpleIcon` shape or the `` Razor tag helper. Use the tag helper from .cshtml files and the shape from Liquid. + +```liquid +{% shape "SimpleIcon", Source: 'youtube', IconClasses: 'h-5 w-5 shrink-0', label-classes: 'font-semibold tracking-wide', Size: 24, Title: 'YouTube', ShowLabel: true %} +``` + +```cshtml + +``` diff --git a/Lombiq.HelpfulExtensions/Extensions/SimpleIcons/SimpleIconTagHelper.cs b/Lombiq.HelpfulExtensions/Extensions/SimpleIcons/SimpleIconTagHelper.cs new file mode 100644 index 00000000..b9612543 --- /dev/null +++ b/Lombiq.HelpfulExtensions/Extensions/SimpleIcons/SimpleIconTagHelper.cs @@ -0,0 +1,38 @@ +using Lombiq.HelpfulLibraries.OrchardCore.TagHelpers; +using Microsoft.AspNetCore.Razor.TagHelpers; +using OrchardCore.DisplayManagement; +using System.Threading.Tasks; + +namespace Lombiq.HelpfulExtensions.Extensions.SimpleIcons; + +[HtmlTargetElement("simple-icon")] +public class SimpleIconTagHelper : ShapeTagHelperBase +{ + [HtmlAttributeName("source")] + public string Source { get; set; } + + [HtmlAttributeName("icon-classes")] + public string IconClasses { get; set; } + + [HtmlAttributeName("label-classes")] + public string LabelClasses { get; set; } + + [HtmlAttributeName("size")] + public int Size { get; set; } + + [HtmlAttributeName("title")] + public string Title { get; set; } + + [HtmlAttributeName("show-label")] + public bool ShowLabel { get; set; } + + public SimpleIconTagHelper(IDisplayHelper displayHelper, IShapeFactory shapeFactory) + : base(displayHelper, shapeFactory) + { + } + + protected override string ShapeType => SimpleIconViewModel.ShapeType; + + protected override ValueTask GetViewModelAsync(TagHelperContext context, TagHelperOutput output) => + ValueTask.FromResult(new SimpleIconViewModel(this)); +} diff --git a/Lombiq.HelpfulExtensions/Extensions/SimpleIcons/SimpleIconViewModel.cs b/Lombiq.HelpfulExtensions/Extensions/SimpleIcons/SimpleIconViewModel.cs new file mode 100644 index 00000000..a0003872 --- /dev/null +++ b/Lombiq.HelpfulExtensions/Extensions/SimpleIcons/SimpleIconViewModel.cs @@ -0,0 +1,50 @@ +#nullable enable + +using OrchardCore.DisplayManagement; +using OrchardCore.DisplayManagement.Views; +using System.Collections.Generic; + +namespace Lombiq.HelpfulExtensions.Extensions.SimpleIcons; + +public class SimpleIconViewModel : ShapeViewModel +{ + public const string ShapeType = "SimpleIcon"; + + public string? Source { get; set; } + public string? IconClasses { get; set; } + public string? LabelClasses { get; set; } + public int Size { get; set; } = 24; + public string? Title { get; set; } + public bool ShowLabel { get; set; } + + public SimpleIconViewModel() => Metadata.Type = ShapeType; + + public SimpleIconViewModel(SimpleIconTagHelper helper) + : this() + { + Source = helper.Source; + IconClasses = helper.IconClasses; + LabelClasses = helper.LabelClasses; + Size = helper.Size; + Title = helper.Title; + ShowLabel = helper.ShowLabel; + } + + public static SimpleIconViewModel FromShape(IShape shape) + { + if (shape.Properties.GetMaybe("ViewModel") is SimpleIconViewModel shapeViewModel) + { + return shapeViewModel; + } + + return new SimpleIconViewModel + { + Source = shape.Properties.GetMaybe(nameof(Source))?.ToString(), + IconClasses = shape.Properties.GetMaybe(nameof(IconClasses))?.ToString(), + LabelClasses = shape.Properties.GetMaybe(nameof(LabelClasses))?.ToString(), + Size = shape.Properties.GetMaybe(nameof(Size)) is int sizeInt ? sizeInt : 24, + Title = shape.Properties.GetMaybe(nameof(Title))?.ToString(), + ShowLabel = shape.Properties.GetMaybe(nameof(ShowLabel)) is true or "true", + }; + } +} diff --git a/Lombiq.HelpfulExtensions/Extensions/SimpleIcons/Startup.cs b/Lombiq.HelpfulExtensions/Extensions/SimpleIcons/Startup.cs new file mode 100644 index 00000000..c947b57c --- /dev/null +++ b/Lombiq.HelpfulExtensions/Extensions/SimpleIcons/Startup.cs @@ -0,0 +1,11 @@ +using Microsoft.Extensions.DependencyInjection; +using OrchardCore.Modules; + +namespace Lombiq.HelpfulExtensions.Extensions.SimpleIcons; + +[Feature(FeatureIds.SimpleIcons)] +public sealed class Startup : StartupBase +{ + public override void ConfigureServices(IServiceCollection services) => + services.AddTagHelpers(); +} diff --git a/Lombiq.HelpfulExtensions/FeatureIds.cs b/Lombiq.HelpfulExtensions/FeatureIds.cs index d4b52ed8..79a29461 100644 --- a/Lombiq.HelpfulExtensions/FeatureIds.cs +++ b/Lombiq.HelpfulExtensions/FeatureIds.cs @@ -18,6 +18,7 @@ public static class FeatureIds public const string Security = FeatureIdPrefix + nameof(Security); public const string ShapeTracing = FeatureIdPrefix + nameof(ShapeTracing); public const string Shortcodes = FeatureIdPrefix + nameof(Shortcodes); + public const string SimpleIcons = FeatureIdPrefix + nameof(SimpleIcons); public const string SiteTexts = FeatureIdPrefix + nameof(SiteTexts); public const string TargetBlank = FeatureIdPrefix + nameof(TargetBlank); public const string Trumbowyg = FeatureIdPrefix + nameof(Trumbowyg); diff --git a/Lombiq.HelpfulExtensions/Manifest.cs b/Lombiq.HelpfulExtensions/Manifest.cs index 3e5b6bea..50f93762 100644 --- a/Lombiq.HelpfulExtensions/Manifest.cs +++ b/Lombiq.HelpfulExtensions/Manifest.cs @@ -187,3 +187,14 @@ "OrchardCore.Resources", ] )] + +[assembly: Feature( + Id = SimpleIcons, + Name = "Lombiq Helpful Extensions - Simple Icons", + Category = "Content", + Description = "Adds the Simple Icons icon library as a resource and the tag helper.", + Dependencies = + [ + "OrchardCore.DisplayManagement", + ] +)] diff --git a/Lombiq.HelpfulExtensions/Views/SimpleIcon.cshtml b/Lombiq.HelpfulExtensions/Views/SimpleIcon.cshtml new file mode 100644 index 00000000..1de9a915 --- /dev/null +++ b/Lombiq.HelpfulExtensions/Views/SimpleIcon.cshtml @@ -0,0 +1,22 @@ +@model OrchardCore.DisplayManagement.IShape + +@using Lombiq.HelpfulExtensions.Extensions.SimpleIcons + +@{ + var viewModel = SimpleIconViewModel.FromShape(Model); + if (string.IsNullOrEmpty(viewModel.Source)) + { + return; + } + + var source = viewModel.Source.EndsWith(".svg") + ? viewModel.Source + : Href($"~/Lombiq.HelpfulExtensions/vendors/simple-icons/icons/{viewModel.Source}.svg"); +} + +@viewModel.Title + +@if (viewModel.ShowLabel) +{ + @viewModel.Title +} \ No newline at end of file diff --git a/Lombiq.HelpfulExtensions/libman.json b/Lombiq.HelpfulExtensions/libman.json index 9d076886..389496cf 100644 --- a/Lombiq.HelpfulExtensions/libman.json +++ b/Lombiq.HelpfulExtensions/libman.json @@ -8,11 +8,23 @@ }, { "library": "trumbowyg@2.31.0", - "files": [ "dist/**/*", "plugins/**/*" ] + "files": [ + "dist/**/*", + "plugins/**/*" + ] }, { - "library": "lucide@1.14.0", - "files": [ "dist/umd/lucide.js", "dist/umd/lucide.min.js" ] + "library": "lucide@1.14.0", + "files": [ + "dist/umd/lucide.js", + "dist/umd/lucide.min.js" + ] + }, + { + "library": "simple-icons@16.19.0", + "files": [ + "icons/*.svg" + ] } ] -} +} \ No newline at end of file