(StringComparer.OrdinalIgnoreCase)
+ {
+ { "name", Name },
+ };
+ }
+
+ var tagBuilder = Generator.GenerateSelect(
+ ViewContext,
+ For.ModelExplorer,
+ optionLabel: null,
+ expression: For.Name,
+ selectList: items,
+ currentValues: CurrentValues,
+ allowMultiple: AllowMultiple,
+ htmlAttributes: htmlAttributes);
+
+ if (tagBuilder != null)
+ {
+ output.MergeAttributes(tagBuilder);
+ if (tagBuilder.HasInnerHtml)
+ {
+ output.PostContent.AppendHtml(tagBuilder.InnerHtml);
+ }
+ }
+
+ output.PreElement.AppendHtml("");
+ // TODO use iconoptions + taghelper
+ output.PostElement.AppendHtml("");
+ output.PostElement.AppendHtml("
");
+
+ return Task.CompletedTask;
+ }
+}
\ No newline at end of file
diff --git a/zero/TagHelpers/ClassTagHelper.cs b/zero/TagHelpers/ClassTagHelper.cs
new file mode 100644
index 00000000..3b4b049f
--- /dev/null
+++ b/zero/TagHelpers/ClassTagHelper.cs
@@ -0,0 +1,38 @@
+using Microsoft.AspNetCore.Razor.TagHelpers;
+
+namespace zero.TagHelpers;
+
+[HtmlTargetElement(Attributes = PREFIX + "*")]
+public class ClassTagHelper : TagHelper
+{
+ private const string PREFIX = "app-class:";
+
+ [HtmlAttributeName("class")]
+ public string Classes { get; set; }
+
+ private IDictionary _classValues;
+
+ [HtmlAttributeName("", DictionaryAttributePrefix = PREFIX)]
+ public IDictionary ClassValues
+ {
+ get => _classValues ?? (_classValues = new Dictionary(StringComparer.OrdinalIgnoreCase));
+ set => _classValues = value;
+ }
+
+
+ public override void Process(TagHelperContext context, TagHelperOutput output)
+ {
+ var items = _classValues.Where(e => e.Value).Select(e => e.Key).ToList();
+
+ if (!String.IsNullOrEmpty(Classes))
+ {
+ items.Insert(0, Classes);
+ }
+
+ if (items.Any())
+ {
+ var classes = String.Join(" ", items.ToArray());
+ output.Attributes.Add("class", classes);
+ }
+ }
+}
\ No newline at end of file
diff --git a/zero/TagHelpers/IconTagHelper.cs b/zero/TagHelpers/IconTagHelper.cs
new file mode 100644
index 00000000..b5ad1d44
--- /dev/null
+++ b/zero/TagHelpers/IconTagHelper.cs
@@ -0,0 +1,68 @@
+using Microsoft.AspNetCore.Razor.TagHelpers;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+
+namespace zero.TagHelpers;
+
+[HtmlTargetElement("app-icon", TagStructure = TagStructure.NormalOrSelfClosing)]
+public class IconTagHelper : TagHelper
+{
+ public string Symbol { get; set; }
+
+ public int Size { get; set; } = -1;
+
+ public decimal Stroke { get; set; } = -1;
+
+ public string Class { get; set; }
+
+
+ private IconOptions _options;
+
+ private readonly ILogger _logger;
+
+
+ public IconTagHelper(IOptionsMonitor options, ILogger logger)
+ {
+ _options = options.CurrentValue;
+ _logger = logger;
+
+ options.OnChange(val => _options = val);
+ }
+
+
+ public override void Process(TagHelperContext context, TagHelperOutput output)
+ {
+ if (_options.Path.IsNullOrWhiteSpace())
+ {
+ _logger.LogWarning("Could not render . Please configure the path with IconOptions before.");
+ output.SuppressOutput();
+ return;
+ }
+
+ int size = Size < 0 ? _options.DefaultSize : Size;
+ string stroke = (Stroke < 0 ? _options.DefaultStrokeWidth : Stroke).ToString().Replace(',', '.');
+
+ output.TagName = "svg";
+ output.Attributes.SetAttribute("class", Class.HasValue() ? $"{_options.CssClass} {Class}" : _options.CssClass);
+ output.Attributes.SetAttribute("width", size);
+ output.Attributes.SetAttribute("height", size);
+ output.Attributes.SetAttribute("xmlns", "http://www.w3.org/2000/svg");
+ output.Attributes.SetAttribute("stroke-width", stroke);
+ output.Attributes.SetAttribute("data-symbol", Symbol);
+ output.Content.SetHtmlContent(BuildIcon(Symbol, size, stroke));
+ }
+
+
+ public string BuildIcon(string symbol, int size = 18, string stroke = "2", string classes = null, bool withSvg = false)
+ {
+ string inner = $"";
+
+ if (!withSvg)
+ {
+ return inner;
+ }
+
+ return $"";
+ }
+}
\ No newline at end of file
diff --git a/zero/TagHelpers/IfTagHelper.cs b/zero/TagHelpers/IfTagHelper.cs
new file mode 100644
index 00000000..37c260fc
--- /dev/null
+++ b/zero/TagHelpers/IfTagHelper.cs
@@ -0,0 +1,17 @@
+using Microsoft.AspNetCore.Razor.TagHelpers;
+
+namespace zero.TagHelpers;
+
+[HtmlTargetElement(Attributes = "app-if")]
+public class IfTagHelper : TagHelper
+{
+ public bool AppIf { get; set; }
+
+ public override void Process(TagHelperContext context, TagHelperOutput output)
+ {
+ if (!AppIf)
+ {
+ output.SuppressOutput();
+ }
+ }
+}
diff --git a/zero/TagHelpers/MultilineTagHelper.cs b/zero/TagHelpers/MultilineTagHelper.cs
new file mode 100644
index 00000000..2c842f70
--- /dev/null
+++ b/zero/TagHelpers/MultilineTagHelper.cs
@@ -0,0 +1,16 @@
+using Microsoft.AspNetCore.Razor.TagHelpers;
+
+namespace zero.TagHelpers;
+
+[HtmlTargetElement("app-multiline", Attributes = "text")]
+public class MultilineTagHelper : TagHelper
+{
+ [HtmlAttributeName("text")]
+ public string Text { get; set; }
+
+ public override void Process(TagHelperContext context, TagHelperOutput output)
+ {
+ output.TagName = string.Empty;
+ output.Content.SetHtmlContent(Text.NewLinesToBr());
+ }
+}
\ No newline at end of file
diff --git a/zero/Media/ImageSharp/ResizeTagHelper.cs b/zero/TagHelpers/ResizeTagHelper.cs
similarity index 86%
rename from zero/Media/ImageSharp/ResizeTagHelper.cs
rename to zero/TagHelpers/ResizeTagHelper.cs
index a63a737b..fa04f5c4 100644
--- a/zero/Media/ImageSharp/ResizeTagHelper.cs
+++ b/zero/TagHelpers/ResizeTagHelper.cs
@@ -4,13 +4,13 @@ using Microsoft.AspNetCore.Razor.TagHelpers;
namespace zero.TagHelpers;
-[HtmlTargetElement(Attributes = "zero-resize")]
+[HtmlTargetElement(Attributes = "app-resize")]
public class ResizeTagHelper : TagHelper
{
[HtmlAttributeName("src")]
public string Src { get; set; }
- [HtmlAttributeName("zero-resize")]
+ [HtmlAttributeName("app-resize")]
public string Preset { get; set; }
[ViewContext]
@@ -28,7 +28,7 @@ public class ResizeTagHelper : TagHelper
public override void Process(TagHelperContext context, TagHelperOutput output)
{
string src = FileVersionProvider.AddFileVersionToPath(ViewContext.HttpContext.Request.PathBase, Src).Resize(Preset);
- output.Attributes.RemoveAll("zero-resize");
+ output.Attributes.RemoveAll("app-resize");
output.Attributes.SetAttribute("src", src);
}
}
\ No newline at end of file
diff --git a/zero/TagHelpers/SelectGenderTagHelper.cs b/zero/TagHelpers/SelectGenderTagHelper.cs
new file mode 100644
index 00000000..928eea8a
--- /dev/null
+++ b/zero/TagHelpers/SelectGenderTagHelper.cs
@@ -0,0 +1,30 @@
+using Microsoft.AspNetCore.Mvc.Rendering;
+using Microsoft.AspNetCore.Mvc.ViewFeatures;
+using Microsoft.AspNetCore.Razor.TagHelpers;
+
+namespace zero.TagHelpers;
+
+[HtmlTargetElement("app-gender-select", Attributes = FOR_ATTRIBUTE_NAME)]
+public class SelectGenderTagHelper : BaseSelectTagHelper
+{
+ ILocalizer _localizer;
+
+ public SelectGenderTagHelper(IHtmlGenerator generator, ILocalizer localizer) : base(generator)
+ {
+ _localizer = localizer;
+ }
+
+
+ public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
+ {
+ Items.Add(new SelectListItem(string.Empty, null));
+
+ foreach (Gender gender in Enum.GetValues())
+ {
+ string key = "forms.gender." + gender.ToString().ToLowerInvariant();
+ Items.Add(new SelectListItem(_localizer.Text(key), gender.ToString()));
+ }
+
+ await base.ProcessAsync(context, output);
+ }
+}
\ No newline at end of file
diff --git a/zero/TagHelpers/StripHtmlTagHelper.cs b/zero/TagHelpers/StripHtmlTagHelper.cs
new file mode 100644
index 00000000..93f26839
--- /dev/null
+++ b/zero/TagHelpers/StripHtmlTagHelper.cs
@@ -0,0 +1,33 @@
+using Microsoft.AspNetCore.Razor.TagHelpers;
+using System.Net;
+using System.Text.RegularExpressions;
+
+namespace zero.TagHelpers;
+
+[HtmlTargetElement("app-striphtml", Attributes = "text")]
+public class StripHtmlTagHelper : TagHelper
+{
+ [HtmlAttributeName("text")]
+ public string Text { get; set; }
+
+ [HtmlAttributeName("maxLength")]
+ public int MaxLength { get; set; } = -1;
+
+ public override void Process(TagHelperContext context, TagHelperOutput output)
+ {
+ output.TagName = string.Empty;
+ string text = string.Empty;
+
+ if (!String.IsNullOrWhiteSpace(Text))
+ {
+ text = WebUtility.HtmlDecode(Regex.Replace(Text, "<[^>]*(>|$)", string.Empty).Trim());
+
+ if (MaxLength > 0 && text.Length > MaxLength)
+ {
+ text = text.Substring(0, MaxLength) + "...";
+ }
+ }
+
+ output.Content.SetHtmlContent(text);
+ }
+}