using Microsoft.AspNetCore.Razor.TagHelpers;
using Microsoft.VisualBasic;
using System.Threading.Tasks;
using AcdiuTools.Constants;
namespace AcdiuTools.TagHelpers
{
///
/// SVG Sprite 封装标签。
/// 支持自动缩放逻辑:若未指定宽高,则默认添加 w-1r/h-1r 类名以适配响应式根字号。
///
///
/// 用法: <bsicon i="heart-fill" w="20" f="red" />
/// 或: <bsicon icon="alarm" width="1rem" cn="my-style" />
///
[HtmlTargetElement("bsicon")]
public class BsIconTagHelper : TagHelper
{
// 内部逻辑变量
private string _iconName = string.Empty;
private string _width = string.Empty;
private string _height = string.Empty;
private string _fill = "currentColor";
#region 属性定义 (支持别名)
///
/// 图标名称 (必填)。对应 SVG 中的 ID。
///
[HtmlAttributeName("i")]
public string I { get => _iconName; set => _iconName = value; }
///
/// 图标名称 (别名)。
///
[HtmlAttributeName("icon")]
public string Icon { get => _iconName; set => _iconName = value; }
///
/// 宽度。支持数字或 CSS 单位(如 16, 1rem)。
/// 若为空则尝试使用高度值,若均为空则添加默认响应式类名。
///
[HtmlAttributeName("w")]
public string W { get => _width; set => _width = value; }
///
/// 宽度 (别名)。
///
[HtmlAttributeName("width")]
public string Width { get => _width; set => _width = value; }
///
/// 高度。支持数字或 CSS 单位。
///
[HtmlAttributeName("h")]
public string H { get => _height; set => _height = value; }
///
/// 高度 (别名)。
///
[HtmlAttributeName("height")]
public string Height { get => _height; set => _height = value; }
///
/// 填充颜色。默认为 currentColor。
///
[HtmlAttributeName("f")]
public string F { get => _fill; set => _fill = value; }
///
/// 填充颜色 (别名)。
///
[HtmlAttributeName("fill")]
public string Fill { get => _fill; set => _fill = value; }
///
/// 自定义 CSS 类名。
///
[HtmlAttributeName("c")]
public string C { get; set; } = string.Empty;
///
/// 自定义 CSS 类名 (别名)。
///
[HtmlAttributeName("cn")]
public string CN { get; set; } = string.Empty;
///
/// 自定义 CSS 类名 (别名)。
///
[HtmlAttributeName("class")]
public string ClassName { get; set; } = string.Empty;
///
/// 自定义 SVG Sprite 路径。
/// 不填则使用系统默认常量路径。
///
[HtmlAttributeName("path")]
public string CustomPath { get; set; } = string.Empty;
#endregion
///
/// 处理标签渲染逻辑
///
public override void Process(TagHelperContext context, TagHelperOutput output)
{
if (string.IsNullOrWhiteSpace(_iconName))
{
output.SuppressOutput();
return;
}
// 1. 设置基础标签属性
output.TagName = "svg";
output.TagMode = TagMode.StartTagAndEndTag;
output.Attributes.SetAttribute("fill", _fill);
output.Attributes.SetAttribute("viewBox", "0 0 16 16");
// 2. 处理宽高与类名逻辑
bool hasW = !string.IsNullOrWhiteSpace(_width);
bool hasH = !string.IsNullOrWhiteSpace(_height);
if (hasW || hasH)
{
// 只要设置了任意一个,就手动赋值 width/height 属性
output.Attributes.SetAttribute("width", hasW ? _width : _height);
output.Attributes.SetAttribute("height", hasH ? _height : _width);
// 设置类名(不添加默认响应式类)
output.Attributes.SetAttribute("class", ClassName);
}
else
{
// 均未设置,则应用响应式默认类名并去重
output.Attributes.SetAttribute("class", BuildResponsiveClasses(ClassName));
}
// 3. 构建内部内容
string finalPath = string.IsNullOrWhiteSpace(CustomPath)
? UIConstants.Paths.DefaultIconSprite
: CustomPath;
output.Content.SetHtmlContent($@"");
}
///
/// 构建响应式类名字符串,确保默认类名存在且去重
///
private string BuildResponsiveClasses(string userClassName)
{
var classes = new HashSet(StringComparer.OrdinalIgnoreCase)
{
UIConstants.Classes.DefaultWidth,
UIConstants.Classes.DefaultHeight
};
if (!string.IsNullOrWhiteSpace(userClassName))
{
var userParts = userClassName.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
foreach (var item in userParts) classes.Add(item);
}
return string.Join(" ", classes);
}
}
}