├── .nvmrc
├── sample
├── Views
│ ├── _ViewImports.cshtml
│ ├── _ViewStart.cshtml
│ ├── Shared
│ │ └── _Layout.cshtml
│ └── Home
│ │ └── Index.cshtml
├── wwwroot
│ └── favicon.ico
├── Controllers
│ └── HomeController.cs
├── appsettings.json
├── Sample.csproj
├── appsettings.Development.json
├── Program.cs
├── Properties
│ └── launchSettings.json
└── Startup.cs
├── .markdownlint.json
├── assets
├── logo.png
├── README.md
└── logo.svg
├── obsolete_icons.txt
├── generator
├── .editorconfig
├── Properties
│ └── launchSettings.json
├── StringBuilderExtensions.cs
├── IconDetails.cs
├── StringExtensions.cs
├── generator.props
├── IconSourceGenerator.csproj
├── IconExtractor.cs
└── IconSourceGenerator.cs
├── nuget.config
├── .github
├── workflows
│ ├── fixup-commits.yml
│ ├── dotnet-sdk-updater.yml
│ ├── dependabot-auto-merge.yml
│ ├── codeql-analysis.yml
│ ├── pull_request.yml
│ ├── ci.yml
│ └── release.yml
└── dependabot.yml
├── Directory.Build.targets
├── package.json
├── .config
└── dotnet-tools.json
├── .vscode
└── settings.json
├── test
├── .editorconfig
├── HeroiconsTagHelperTests.csproj
├── TagHelperTestBase.cs
├── IconFocusableTagHelperTests.cs
├── IconListTests.cs
├── IconAccessibilityTagHelperTests.cs
└── IconTagHelperTests.cs
├── global.json
├── src
├── HeroiconOptions.cs
├── IconFocusableTagHelper.cs
├── HeroiconsExtensions.cs
├── IconAccessibilityTagHelper.cs
├── HeroiconsTagHelper.csproj
└── IconTagHelper.cs
├── LICENSE
├── Directory.Build.props
├── analysis
├── code-style.editorconfig
├── code-quality.editorconfig
└── roslynator.editorconfig
├── .gitattributes
├── HeroiconsTagHelper.sln
├── .editorconfig
├── README.md
├── .gitignore
└── CHANGELOG.md
/.nvmrc:
--------------------------------------------------------------------------------
1 | 21
2 |
--------------------------------------------------------------------------------
/sample/Views/_ViewImports.cshtml:
--------------------------------------------------------------------------------
1 | @addTagHelper *, HeroiconsTagHelper
2 |
--------------------------------------------------------------------------------
/sample/Views/_ViewStart.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | Layout = "_Layout";
3 | }
4 |
--------------------------------------------------------------------------------
/.markdownlint.json:
--------------------------------------------------------------------------------
1 | {
2 | "MD013": false,
3 | "MD033": false,
4 | "MD045": false
5 | }
6 |
--------------------------------------------------------------------------------
/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xt0rted/heroicons-tag-helper/HEAD/assets/logo.png
--------------------------------------------------------------------------------
/sample/wwwroot/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xt0rted/heroicons-tag-helper/HEAD/sample/wwwroot/favicon.ico
--------------------------------------------------------------------------------
/obsolete_icons.txt:
--------------------------------------------------------------------------------
1 | arrow-left-on-rectangle
2 | arrow-right-on-rectangle
3 | arrow-small-down
4 | arrow-small-left
5 | arrow-small-right
6 | arrow-small-up
7 | minus-small
8 | plus-small
9 |
--------------------------------------------------------------------------------
/generator/.editorconfig:
--------------------------------------------------------------------------------
1 | [*.cs]
2 | # IDE0079: Remove unnecessary suppression
3 | dotnet_diagnostic.IDE0079.severity = none
4 |
5 | # RS2008: Enable analyzer release tracking
6 | dotnet_diagnostic.RS2008.severity = none
7 |
--------------------------------------------------------------------------------
/sample/Controllers/HomeController.cs:
--------------------------------------------------------------------------------
1 | namespace Sample.Controllers;
2 |
3 | using Microsoft.AspNetCore.Mvc;
4 |
5 | public class HomeController : Controller
6 | {
7 | public IActionResult Index() => View();
8 | }
9 |
--------------------------------------------------------------------------------
/generator/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "profiles": {
3 | "HeroiconsTagHelper": {
4 | "commandName": "DebugRoslynComponent",
5 | "targetProject": "..\\src\\HeroiconsTagHelper.csproj"
6 | }
7 | }
8 | }
--------------------------------------------------------------------------------
/nuget.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/sample/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "AllowedHosts": "*",
3 | "Logging": {
4 | "LogLevel": {
5 | "Default": "Information",
6 | "Microsoft": "Warning",
7 | "Microsoft.Hosting.Lifetime": "Information"
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/.github/workflows/fixup-commits.yml:
--------------------------------------------------------------------------------
1 | name: Block on fixup commits
2 |
3 | on: pull_request_target
4 |
5 | permissions:
6 | pull-requests: read
7 |
8 | jobs:
9 | message:
10 | uses: xt0rted/.github/.github/workflows/fixup-commits.yml@main
11 |
--------------------------------------------------------------------------------
/Directory.Build.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "heroicons-tag-helper",
3 | "private": true,
4 | "scripts": {
5 | "test": "markdownlint \"**/*.md\" --ignore node_modules"
6 | },
7 | "dependencies": {
8 | "heroicons": "2.1.3"
9 | },
10 | "devDependencies": {
11 | "markdownlint-cli": "^0.47.0"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/.config/dotnet-tools.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 1,
3 | "isRoot": true,
4 | "tools": {
5 | "run-script": {
6 | "version": "0.6.0",
7 | "commands": [
8 | "r"
9 | ]
10 | },
11 | "rimraf": {
12 | "version": "0.3.1",
13 | "commands": [
14 | "rimraf"
15 | ]
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "cSpell.words": [
3 | "cref",
4 | "evenodd",
5 | "heroicon",
6 | "heroicons",
7 | "inheritdoc",
8 | "labeledby",
9 | "linecap",
10 | "linejoin",
11 | "viewbox"
12 | ],
13 | "dotnet.defaultSolution": "HeroiconsTagHelper.sln"
14 | }
15 |
--------------------------------------------------------------------------------
/sample/Sample.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $(_TargetFramework)
5 | 1701;1702;CS0618
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/sample/Views/Shared/_Layout.cshtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Sample
7 |
8 |
9 |
10 | @RenderBody()
11 |
12 |
13 |
--------------------------------------------------------------------------------
/sample/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Heroicons": {
3 | "IncludeComments": true,
4 | "SetAccessibilityAttributes": true,
5 | "SetFocusableAttribute": true
6 | },
7 | "Logging": {
8 | "LogLevel": {
9 | "Default": "Information",
10 | "Microsoft": "Warning",
11 | "Microsoft.Hosting.Lifetime": "Information"
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/.github/workflows/dotnet-sdk-updater.yml:
--------------------------------------------------------------------------------
1 | name: .NET SDK updater
2 |
3 | on:
4 | schedule:
5 | - cron: "0 12 * * 1-5"
6 | workflow_dispatch:
7 |
8 | jobs:
9 | update:
10 | uses: xt0rted/.github/.github/workflows/dotnet-sdk-updater.yml@main
11 | secrets:
12 | DOTNET_UPDATER_APP_ID: ${{ secrets.DOTNET_UPDATER_APP_ID }}
13 | DOTNET_UPDATER_PRIVATE_KEY: ${{ secrets.DOTNET_UPDATER_PRIVATE_KEY }}
14 |
--------------------------------------------------------------------------------
/generator/StringBuilderExtensions.cs:
--------------------------------------------------------------------------------
1 | namespace IconSourceGenerator;
2 |
3 | internal static class StringBuilderExtensions
4 | {
5 | public static StringBuilder AppendLine(this StringBuilder builder, params string[] value)
6 | {
7 | for (var i = 0; i < value.Length; i++)
8 | {
9 | builder.Append(value[i]);
10 | }
11 |
12 | return builder.AppendLine();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/sample/Program.cs:
--------------------------------------------------------------------------------
1 | namespace Sample;
2 |
3 | public static class Program
4 | {
5 | public static void Main(string[] args)
6 | => CreateHostBuilder(args)
7 | .Build()
8 | .Run();
9 |
10 | public static IHostBuilder CreateHostBuilder(string[] args)
11 | => Host.CreateDefaultBuilder(args)
12 | .ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup());
13 | }
14 |
--------------------------------------------------------------------------------
/generator/IconDetails.cs:
--------------------------------------------------------------------------------
1 | namespace IconSourceGenerator;
2 |
3 | internal class IconDetails
4 | {
5 | public string Path { get; set; } = null!;
6 |
7 | public string Name { get; set; } = null!;
8 |
9 | public string ClassName { get; set; } = null!;
10 |
11 | public string Style { get; set; } = null!;
12 |
13 | public bool UsesStroke { get; set; }
14 |
15 | public AdditionalText File { get; set; } = null!;
16 | }
17 |
--------------------------------------------------------------------------------
/test/.editorconfig:
--------------------------------------------------------------------------------
1 | [*.cs]
2 | # CA1063: Implement IDisposable Correctly
3 | dotnet_diagnostic.CA1063.severity = none
4 |
5 | # CA1707: Identifiers should not contain underscores
6 | dotnet_diagnostic.CA1707.severity = none
7 |
8 | # CA1816: Dispose methods should call SuppressFinalize
9 | dotnet_diagnostic.CA1816.severity = none
10 |
11 | # CA2234: Pass system uri objects instead of strings
12 | dotnet_diagnostic.CA2234.severity = none
13 |
14 | # CS8618: Non-nullable field is uninitialized. Consider declaring as nullable.
15 | dotnet_diagnostic.CS8618.severity = none
16 |
--------------------------------------------------------------------------------
/assets/README.md:
--------------------------------------------------------------------------------
1 | # Assets
2 |
3 | The source for the logo is available on [Figma](https://www.figma.com/file/FBPemu54a3c2fWO55x8bDr/heroicons-tag-helper).
4 | It's a mix of the `arrow-narrow-right` and `shield-exclamation` outline variant icons in v0.4.2.
5 |
6 | The colors used are `#A65FEC` (grape from the [heroicons.com repo](https://github.com/tailwindlabs/heroicons.com/blob/015d9ece75b1ad1fe44e82914777f2c5170d4e74/tailwind.config.js#L27)) and `#6b7280` (`gray-500` from TailwindUI).
7 |
8 | Format | Preview
9 | :-- | :--:
10 | `.png` | 
11 | `.svg` | 
12 |
--------------------------------------------------------------------------------
/global.json:
--------------------------------------------------------------------------------
1 | {
2 | "sdk": {
3 | "version": "8.0.415"
4 | },
5 | "scripts": {
6 | "clean": "dotnet rimraf artifacts",
7 | "clean:bin": "dotnet rimraf **/bin **/obj",
8 | "build": "dotnet build",
9 | "test": "dotnet test",
10 | "test:6": "dotnet test --framework net6.0",
11 | "test:8": "dotnet test --framework net8.0",
12 | "pack": "dotnet pack --output ./artifacts",
13 | "ci": "dotnet r build test pack",
14 | "watch": "dotnet r [env:DOTNET_WATCH_RESTART_ON_RUDE_EDIT=true] watch:sample",
15 | "watch:sample": "dotnet watch --verbose --project sample"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/generator/StringExtensions.cs:
--------------------------------------------------------------------------------
1 | namespace IconSourceGenerator;
2 |
3 | internal static class StringExtensions
4 | {
5 | public static string FirstCharToUpper(this string input)
6 | {
7 | var arr = input.ToCharArray();
8 |
9 | arr[0] = char.ToUpperInvariant(arr[0]);
10 |
11 | return new string(arr);
12 | }
13 |
14 | public static string ToPascalCase(this string name)
15 | {
16 | var splitName = name.Split('-');
17 |
18 | for (var i = 0; i < splitName.Length; i++)
19 | {
20 | splitName[i] = FirstCharToUpper(splitName[i]);
21 | }
22 |
23 | return string.Concat(splitName);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/generator/generator.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | <_AdditionalFilesCleanup Include="@(AdditionalFiles)" />
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/assets/logo.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/sample/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:57627",
7 | "sslPort": 44382
8 | }
9 | },
10 | "profiles": {
11 | "IIS Express": {
12 | "commandName": "IISExpress",
13 | "launchBrowser": true,
14 | "environmentVariables": {
15 | "ASPNETCORE_ENVIRONMENT": "Development"
16 | }
17 | },
18 | "sample": {
19 | "commandName": "Project",
20 | "launchBrowser": true,
21 | "applicationUrl": "https://localhost:5001;http://localhost:5000",
22 | "environmentVariables": {
23 | "ASPNETCORE_ENVIRONMENT": "Development"
24 | }
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/generator/IconSourceGenerator.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 | true
6 | false
7 | true
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/.github/workflows/dependabot-auto-merge.yml:
--------------------------------------------------------------------------------
1 | name: Dependabot auto-merge
2 |
3 | on: pull_request_target
4 |
5 | permissions:
6 | contents: read
7 | pull-requests: read
8 |
9 | jobs:
10 | dependabot:
11 | uses: xt0rted/.github/.github/workflows/dependabot-auto-merge.yml@main
12 | secrets:
13 | GITHUB_APP_ID: ${{ secrets.DEPENDAMERGE_APP_ID }}
14 | GITHUB_APP_PRIVATE_KEY: ${{ secrets.DEPENDAMERGE_PRIVATE_KEY }}
15 | with:
16 | allowed-groups: |
17 | {
18 | "github_actions": [
19 | "github-actions",
20 | "my-actions",
21 | ],
22 | "nuget": [
23 | "analyzers",
24 | "testing",
25 | ],
26 | }
27 | allowed-packages: |
28 | {
29 | "nuget": [
30 | "rimraf",
31 | "run-script",
32 | ],
33 | }
34 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 |
4 | - package-ecosystem: "github-actions"
5 | directory: "/"
6 | schedule:
7 | interval: "weekly"
8 | groups:
9 | github-actions:
10 | patterns:
11 | - "actions/*"
12 | my-actions:
13 | patterns:
14 | - "xt0rted/*"
15 |
16 | - package-ecosystem: "npm"
17 | directory: "/"
18 | schedule:
19 | interval: "weekly"
20 |
21 | - package-ecosystem: "nuget"
22 | directory: "/"
23 | schedule:
24 | interval: "weekly"
25 | groups:
26 | analyzers:
27 | patterns:
28 | - "IDisposableAnalyzers"
29 | - "Roslynator.*"
30 | testing:
31 | patterns:
32 | - "GitHubActionsTestLogger"
33 | - "Microsoft.NET.Test.Sdk"
34 | - "Shouldly"
35 | - "xunit"
36 | - "xunit.*"
37 |
--------------------------------------------------------------------------------
/src/HeroiconOptions.cs:
--------------------------------------------------------------------------------
1 | namespace Tailwind.Heroicons;
2 |
3 | ///
4 | /// Global settings used when emitting Heroicons.
5 | ///
6 | public class HeroiconOptions
7 | {
8 | ///
9 | /// Add an html comment before the svg tag with the style and name of the icon to help make development/debugging easier.
10 | ///
11 | /// This is off by default.
12 | public bool IncludeComments { get; set; }
13 |
14 | ///
15 | /// Adds various accessibility attributes based on the default state of the tag.
16 | ///
17 | /// This is off by default.
18 | public bool SetAccessibilityAttributes { get; set; }
19 |
20 | ///
21 | /// Adds the focusable attribute set to false to prevent the icon from receiving focus in Internet Explorer and Edge Legacy.
22 | ///
23 | /// This is off by default.
24 | public bool SetFocusableAttribute { get; set; }
25 | }
26 |
--------------------------------------------------------------------------------
/generator/IconExtractor.cs:
--------------------------------------------------------------------------------
1 | namespace IconSourceGenerator;
2 |
3 | internal static class IconExtractor
4 | {
5 | private static readonly Regex ViewBoxRegEx = new("viewBox=\"(?[^\"]+)\"", RegexOptions.Compiled);
6 | private static readonly Regex StrokeWidthRegEx = new("stroke-width=\"(?[^\"]+)\"", RegexOptions.Compiled);
7 |
8 | public static string GetPaths(string icon)
9 | {
10 | var lines = icon.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries).Select(path => path.Trim()).ToArray();
11 |
12 | var paths = lines.Skip(1).Take(lines.Length - 2);
13 |
14 | return string.Concat(paths);
15 | }
16 |
17 | public static string GetViewBox(string icon)
18 | {
19 | var match = ViewBoxRegEx.Match(icon);
20 |
21 | return match.Groups["viewbox"].Value;
22 | }
23 |
24 | public static string GetStrokeWidth(string icon)
25 | {
26 | var match = StrokeWidthRegEx.Match(icon);
27 |
28 | return match.Groups["width"].Value;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Brian Surowiec
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/sample/Startup.cs:
--------------------------------------------------------------------------------
1 | namespace Sample;
2 |
3 | public class Startup
4 | {
5 | public Startup(IConfiguration configuration)
6 | => Configuration = configuration;
7 |
8 | public IConfiguration Configuration { get; }
9 |
10 | // This method gets called by the runtime. Use this method to add services to the container.
11 | public void ConfigureServices(IServiceCollection services)
12 | {
13 | services.AddControllersWithViews();
14 |
15 | services.AddHeroicons(Configuration);
16 | }
17 |
18 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
19 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
20 | {
21 | if (env.IsDevelopment())
22 | {
23 | app.UseDeveloperExceptionPage();
24 | }
25 |
26 | app.UseHttpsRedirection();
27 | app.UseStaticFiles();
28 |
29 | app.UseRouting();
30 |
31 | app.UseEndpoints(endpoints =>
32 | {
33 | endpoints.MapControllerRoute(
34 | name: "default",
35 | pattern: "{controller=Home}/{action=Index}/{id?}");
36 | });
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | name: "CodeQL"
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | pull_request:
8 | branches:
9 | - main
10 | schedule:
11 | - cron: "0 6 * * 1"
12 | workflow_dispatch:
13 |
14 | concurrency:
15 | group: ${{ github.workflow }}-${{ github.ref }}
16 | cancel-in-progress: true
17 |
18 | env:
19 | DOTNET_NOLOGO: true
20 | FORCE_COLOR: 3
21 |
22 | jobs:
23 | analyze:
24 | name: Analyze
25 |
26 | runs-on: ubuntu-latest
27 |
28 | permissions:
29 | actions: read
30 | contents: read
31 | security-events: write
32 |
33 | strategy:
34 | fail-fast: false
35 | matrix:
36 | language:
37 | - csharp
38 |
39 | steps:
40 | - name: Check out repository
41 | uses: actions/checkout@v5.0.0
42 |
43 | - name: Set up Node
44 | uses: actions/setup-node@v6.0.0
45 | with:
46 | node-version-file: .nvmrc
47 |
48 | - run: npm ci
49 |
50 | - name: Initialize CodeQL
51 | uses: github/codeql-action/init@v4
52 | with:
53 | languages: ${{ matrix.language }}
54 |
55 | - name: Autobuild
56 | uses: github/codeql-action/autobuild@v4
57 |
58 | - name: Perform CodeQL Analysis
59 | uses: github/codeql-action/analyze@v4
60 |
--------------------------------------------------------------------------------
/test/HeroiconsTagHelperTests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $(_TargetFrameworks)
5 | Tailwind.Heroicons
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | all
18 | runtime; build; native; contentfiles; analyzers
19 |
20 |
21 |
22 |
23 |
24 | all
25 | runtime; build; native; contentfiles; analyzers; buildtransitive
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/test/TagHelperTestBase.cs:
--------------------------------------------------------------------------------
1 | namespace Tailwind.Heroicons;
2 |
3 | public abstract class TagHelperTestBase
4 | {
5 | protected static TagHelperContext MakeTagHelperContext(string tagName, TagHelperAttributeList? attributes = null)
6 | {
7 | attributes ??= new TagHelperAttributeList();
8 |
9 | return new TagHelperContext(
10 | tagName,
11 | allAttributes: attributes,
12 | items: new Dictionary