Skip to content

Commit

Permalink
v1.0.0 (#23)
Browse files Browse the repository at this point in the history
- Custom styles
- Added IApplicationBuilder support (fixes #21)
- New style type to avoid loading additional JS for modern styles
- Fixes and enhancements
- Added NSwag support
  • Loading branch information
teociaps authored Aug 19, 2024
2 parents 939f452 + 0b30598 commit 017da0f
Show file tree
Hide file tree
Showing 69 changed files with 2,572 additions and 370 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pack_and_deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
- published

env:
PROJECTS_PATH: 'src/*'
PROJECTS_PATH: 'src/*.Themes'
CONFIGURATION: 'Release'
PACKAGE_OUTPUT: ${{ github.workspace }}/artifacts
NUGET_SOURCE_URL: 'https://api.nuget.org/v3/index.json'
Expand Down
195 changes: 153 additions & 42 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,41 +14,40 @@
<a href="https://github.com/teociaps/SwaggerUI.Themes/actions/workflows/test.yml">
<img alt="Tests Passing" src="https://github.com/teociaps/SwaggerUI.Themes/actions/workflows/test.yml/badge.svg" />
</a>
<a href="https://www.nuget.org/packages/AspNetCore.SwaggerUI.Themes">
<img alt="NuGet Version" src="https://img.shields.io/nuget/v/AspNetCore.SwaggerUI.Themes?logo=nuget&color=blue" />
</a>
</p>
<span align="center">

**AspNetCore.SwaggerUI.Themes** is a package that extends [Swashbuckle.AspNetCore.SwaggerUI](https://github.com/domaindrivendev/Swashbuckle.AspNetCore) to provide new themes for Swagger documentation in ASP.NET Core applications.
Change style to your API documentation in ASP.NET Core applications!

</span>
<hr>

| Package | Purpose |
| ------- | ------- |
| ![Swashbuckle Nuget Version] | Customize the style for [Swashbuckle.AspNetCore.SwaggerUI] |
| ![NSwag Nuget Version] | Customize the style for [NSwag.AspNetCore] |

## Introduction
[Swashbuckle.AspNetCore](https://github.com/domaindrivendev/Swashbuckle.AspNetCore) is a popular library for adding Swagger support to ASP.NET Core projects, making it easier to document and interact with your APIs.

**AspNetCore.SwaggerUI.Themes** builds upon Swashbuckle.AspNetCore.SwaggerUI, enhancing the Swagger UI with modern and visually appealing themes.
> [!WARNING]
> Starting from v1.0.0 the namespace for pre-defined styles is `AspNetCore.Swagger.Themes` instead of `AspNetCore.SwaggerUI.Themes`!

## Features
- _New Themes_: enhances the Swagger documentation interface with various themes, including a default style that preserves the classic Swagger UI appearance and introduces new modern styles. Explore samples [here](#available-themes).
- _Seamless Integration_: simply install the package and add the style parameter to the existing method used for SwaggerUI.

> [!TIP]
> Opt for Modern Styles! Modern styles come with additional functionalities, including _**pinned topbar**_ and _**back-to-top button**_.
- _Seamless Integration_: simply install the package and add the style parameter to the existing method used for Swagger UI.
- 🆕 _Custom Styles_: create your own style for Swagger documentation. You can either inherit from the classic or modern common styles, or define a completely new style (see more [here](#custom-styles)).


## Supported .NET Versions
| Version | Status |
| ------- | ------------- |
| Version | Status |
| ------- | ------ |
| .NET 6 | ![Badge](https://img.shields.io/badge/Status-Supported-brightgreen) |
| .NET 7 | ![Badge](https://img.shields.io/badge/Status-Supported-brightgreen) |
| .NET 8 | ![Badge](https://img.shields.io/badge/Status-Supported-brightgreen) |


## Getting Started
To use **AspNetCore.SwaggerUI.Themes** in your ASP.NET Core project, follow these steps:
## Swashbuckle.AspNetCore.SwaggerUI
Customize the Swashbuckle API documentation UI by using **AspNetCore.SwaggerUI.Themes** in your ASP.NET Core project:

1. Install the package using .NET CLI or NuGet Package Manager:

Expand All @@ -62,51 +61,53 @@ To use **AspNetCore.SwaggerUI.Themes** in your ASP.NET Core project, follow thes
Install-Package AspNetCore.SwaggerUI.Themes
```

2. In your `Program.cs` file, add the style through the `Style` or `ModernStyle` class as new parameter of `app.UseSwaggerUI()` method:
2. In your `Program.cs` file, add the style through the `Style`, `ModernStyle` or `NoJsModernStyle` class as new parameter of `app.UseSwaggerUI()` method:

```csharp
using AspNetCore.SwaggerUI.Themes;
using AspNetCore.Swagger.Themes;

...

app.UseSwaggerUI(Style.Dark);
app.UseSwaggerUI(ModernStyle.Dark, options => ...);
```

This code enables the chosen theme for Swagger UI in your application.

> [!NOTE]
> Using the `InjectStylesheet()` method in the Swagger UI configuration will override the provided style.
> See [here](#custom-styles) how to inject custom styles.
> [!NOTE]
> Please be aware that for projects utilizing the older style template with separate `Startup.cs` and `Program.cs` files, the previously code should be configured within the `Configure` method of the `Startup` class.

## NSwag.AspNetCore
Customize the NSwag API documentation UI by using **AspNetCore.NSwag.Themes** in your ASP.NET Core project:

## Example
Here's an example of how to integrate AspNetCore.SwaggerUI.Themes in your ASP.NET Core application:
1. Install the package using .NET CLI or NuGet Package Manager:

```csharp
using AspNetCore.SwaggerUI.Themes;
...
```bash
dotnet add package AspNetCore.NSwag.Themes
```

// Add services to the container. Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
or

...
```bash
Install-Package AspNetCore.NSwag.Themes
```

// Use Swagger middleware
app.UseSwagger();
2. In your `Program.cs` file, add the style through the `Style`, `ModernStyle` or `NoJsModernStyle` class as new parameter of `app.UseSwaggerUi()` method:

// Enable the dark theme for Swagger UI
app.UseSwaggerUI(ModernStyle.Dark, c =>
{
// Your Swagger UI configuration here (optional)
});
```csharp
using AspNetCore.Swagger.Themes;

...
```
...

That's it! Your Swagger UI will now have a sleek dark theme.
app.UseSwaggerUi(ModernStyle.Dark, settings => ...);
```

> [!IMPORTANT]
> Using the `InjectStylesheet()` method in the Swagger UI configuration will override the provided style.
This code enables the chosen theme for Swagger UI in your application.

> [!NOTE]
> Setting the `CustomInlineStyles` property while configuring the NSwag settings will override the provided style.
> See [here](#custom-styles) how to inject custom styles.

## Available Themes
Expand All @@ -133,11 +134,114 @@ There are a few pre-defined styles available for your Swagger UI.
| ![modern deepSea style example image] | ![modern desert style example image] | ![modern futuristic style example image] |
| <center><pre lang="csharp">`ModernStyle.DeepSea`</pre></center> | <center><pre lang="csharp">`ModernStyle.Desert`</pre></center> | <center><pre lang="csharp">`ModernStyle.Futuristic`</pre></center> |

> [!TIP]
> Opt for Modern Styles! Modern styles come with additional functionalities, including _**pinned topbar**_ and _**back-to-top button**_.
🆕You can also choose for a version without additional JavaScript if desired by using the pre-built `NoJsModernStyle` class.

> [!NOTE]
> The classic and modern **dark styles** will only load if your browser's color scheme preference is set to _dark_; otherwise, the light style is loaded.

## 🆕Custom Styles
You can customize the Swagger UI in your ASP.NET Core application by applying custom CSS styles.
Here are the available methods.

### Inline CSS Styles
You can directly write your custom CSS content as a string and apply it to the Swagger UI:

```csharp
var cssContent = "body { background-color: #f5f5f5; }";

// Swashbuckle
app.UseSwaggerUI(cssContent, options => ...);

// NSwag
app.UseSwaggerUi(cssContent, settings => ...);
```

### Applying Embedded CSS Files from Assemblies
To apply a CSS file that is embedded as a resource within an assembly, place the file in a folder named **"SwaggerThemes"** inside the assembly.
Then, specify the CSS filename and the assembly where the file is located:

```csharp
var assembly = Assembly.GetExecutingAssembly();
var cssFileName = "myCustomStyle.css"; // Only the filename, no need to specify the "SwaggerThemes" folder
// Swashbuckle
app.UseSwaggerUI(assembly, cssFileName, options => ...);

// NSwag
app.UseSwaggerUi(assembly, cssFileName, settings => ...);
```

> [!NOTE]
> If your CSS file's name starts with **"classic."** or **"modern."**, the method automatically prepends a related common style (either classic or modern) to your custom styles.
> These common styles serve as the base for [pre-defined styles](#available-themes) that enhance the Swagger UI.
### Creating Custom Styles by Inheriting from Base Classes
Another powerful customization option is to create your own style classes by inheriting from the `Style`, `ModernStyle` or `NoJsModernStyle` base classes.
This approach allows you to define new styles that automatically incorporate common base styles and, for modern themes, additional JavaScript.

Here’s how to create a custom style:

```csharp
// Use modern style loading additional JS
public class CustomModernStyle : ModernStyle
{
protected CustomModernStyle(string fileName) : base(fileName)
{
}

public static CustomModernStyle CustomModern => new("modern.custom.css");
}

// Use modern style without loading additional JS
public class CustomNoJsModernStyle : NoJsModernStyle
{
protected CustomNoJsModernStyle(string fileName) : base(fileName)
{
}

public static CustomNoJsModernStyle CustomModern => new("modern.custom.css");
}

// Use classic style
public class CustomStyle : Style
{
protected CustomStyle(string fileName) : base(fileName)
{
}

public static CustomStyle Custom => new("custom.css");
}
```

Place your CSS file (e.g., "custom.css") as an embedded resource in the same assembly where your custom style class is located.
Then, apply it to the Swagger UI:

```csharp
var customStyle = CustomStyle.Custom;

// Swashbuckle
app.UseSwaggerUI(customStyle, options => ...);

// NSwag
app.UseSwaggerUi(customStyle, settings => ...);
```

> [!NOTE]
> Custom styles that inherit from the `ModernStyle` class include additional JavaScript.
> This doesn't apply to styles that inherit from `NoJsModernStyle`, inline styles, or those applied directly from assemblies.

## Contributing
If you have any suggestions, bug reports, or contributions, feel free to open an [issue](https://github.com/teociaps/SwaggerUI.Themes/issues) or submit a [pull request](https://github.com/teociaps/SwaggerUI.Themes/pulls)





[Dark Style Example Image]: https://raw.githubusercontent.com/teociaps/SwaggerUI.Themes/main/samples/screenshots/default-dark.png
[Forest Style Example Image]: https://raw.githubusercontent.com/teociaps/SwaggerUI.Themes/main/samples/screenshots/default-forest.png
[DeepSea Style Example Image]: https://raw.githubusercontent.com/teociaps/SwaggerUI.Themes/main/samples/screenshots/default-deepsea.png
Expand All @@ -148,4 +252,11 @@ If you have any suggestions, bug reports, or contributions, feel free to open an
[Modern Forest Style Example Image]: https://raw.githubusercontent.com/teociaps/SwaggerUI.Themes/main/samples/screenshots/modern-forest.png
[Modern DeepSea Style Example Image]: https://raw.githubusercontent.com/teociaps/SwaggerUI.Themes/main/samples/screenshots/modern-deepsea.png
[Modern Desert Style Example Image]: https://raw.githubusercontent.com/teociaps/SwaggerUI.Themes/main/samples/screenshots/modern-desert.png
[Modern Futuristic Style Example Image]: https://raw.githubusercontent.com/teociaps/SwaggerUI.Themes/main/samples/screenshots/modern-futuristic.png
[Modern Futuristic Style Example Image]: https://raw.githubusercontent.com/teociaps/SwaggerUI.Themes/main/samples/screenshots/modern-futuristic.png


[Swashbuckle Nuget Version]: https://img.shields.io/nuget/v/AspNetCore.SwaggerUI.Themes?logo=nuget&label=AspNetCore.SwaggerUI.Themes&color=blue
[NSwag Nuget Version]: https://img.shields.io/nuget/v/AspNetCore.NSwag.Themes?logo=nuget&label=AspNetCore.NSwag.Themes&color=blue

[Swashbuckle.AspNetCore.SwaggerUI]: https://github.com/domaindrivendev/Swashbuckle.AspNetCore
[NSwag.AspNetCore]: https://github.com/RicoSuter/NSwag?tab=readme-ov-file#aspnet-and-aspnet-core
23 changes: 22 additions & 1 deletion SwaggerUI.Themes.sln
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.AspNetCore.SwaggerUI
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{B89F6FD2-68B6-4A70-A070-FF22FE42DDE4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNetCore.SwaggerUI.Themes.Tests", "tests\AspNetCore.SwaggerUI.Themes.Tests\AspNetCore.SwaggerUI.Themes.Tests.csproj", "{540CD242-4352-4C39-ADBA-572D2795B160}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNetCore.Swagger.Themes.Tests", "tests\AspNetCore.SwaggerUI.Themes.Tests\AspNetCore.Swagger.Themes.Tests.csproj", "{540CD242-4352-4C39-ADBA-572D2795B160}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.AspNetCore.SwaggerUI.NSwag", "samples\Sample.AspNetCore.SwaggerUI.NSwag\Sample.AspNetCore.SwaggerUI.NSwag.csproj", "{E8C376AC-9933-4ECF-92D8-66BC706FD6D0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNetCore.NSwag.Themes", "src\AspNetCore.NSwag.Themes\AspNetCore.NSwag.Themes.csproj", "{38614F76-C962-4CDC-9C9D-25469B92CDE2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AspNetCore.Swagger.Themes.Common", "src\AspNetCore.Swagger.Themes.Common\AspNetCore.Swagger.Themes.Common.csproj", "{DCD47D0E-ADD5-4B6A-BDAA-DD6559EB384D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -41,6 +47,18 @@ Global
{540CD242-4352-4C39-ADBA-572D2795B160}.Debug|Any CPU.Build.0 = Debug|Any CPU
{540CD242-4352-4C39-ADBA-572D2795B160}.Release|Any CPU.ActiveCfg = Release|Any CPU
{540CD242-4352-4C39-ADBA-572D2795B160}.Release|Any CPU.Build.0 = Release|Any CPU
{E8C376AC-9933-4ECF-92D8-66BC706FD6D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E8C376AC-9933-4ECF-92D8-66BC706FD6D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E8C376AC-9933-4ECF-92D8-66BC706FD6D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E8C376AC-9933-4ECF-92D8-66BC706FD6D0}.Release|Any CPU.Build.0 = Release|Any CPU
{38614F76-C962-4CDC-9C9D-25469B92CDE2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{38614F76-C962-4CDC-9C9D-25469B92CDE2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{38614F76-C962-4CDC-9C9D-25469B92CDE2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{38614F76-C962-4CDC-9C9D-25469B92CDE2}.Release|Any CPU.Build.0 = Release|Any CPU
{DCD47D0E-ADD5-4B6A-BDAA-DD6559EB384D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DCD47D0E-ADD5-4B6A-BDAA-DD6559EB384D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DCD47D0E-ADD5-4B6A-BDAA-DD6559EB384D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DCD47D0E-ADD5-4B6A-BDAA-DD6559EB384D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -49,6 +67,9 @@ Global
{5FC2CEDA-5475-4096-BDEC-1C9BFC933FB8} = {19896985-FCB0-4EA0-8E5F-FF3902AC13FC}
{ED52DF52-839F-4DFE-ABDD-05C8F85D71BC} = {FF08B180-6923-46E0-8426-99391CFB47CD}
{540CD242-4352-4C39-ADBA-572D2795B160} = {B89F6FD2-68B6-4A70-A070-FF22FE42DDE4}
{E8C376AC-9933-4ECF-92D8-66BC706FD6D0} = {FF08B180-6923-46E0-8426-99391CFB47CD}
{38614F76-C962-4CDC-9C9D-25469B92CDE2} = {19896985-FCB0-4EA0-8E5F-FF3902AC13FC}
{DCD47D0E-ADD5-4B6A-BDAA-DD6559EB384D} = {19896985-FCB0-4EA0-8E5F-FF3902AC13FC}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {660A434B-79DE-4C3F-892C-333338978C59}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#pragma warning disable S1133 // Deprecated code should be removed - Done for testing purposes
#pragma warning disable CS0618 // Type or member is obsolete - Done for testing purposes

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.ComponentModel.DataAnnotations;

namespace Controllers;

[ApiController]
[Route("sample")]
public class SampleController : ControllerBase
{
[HttpHead("head")]
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public IActionResult HeadSample([Required] int sample)
{
return Ok(sample);
}

[HttpPatch("patch")]
[ProducesResponseType(typeof(Models.Sample), StatusCodes.Status200OK)]
[Produces("application/json")]
public IActionResult PatchSample(Models.Sample model)
{
return Ok(model);
}

[HttpOptions("options")]
[Authorize]
public IActionResult OptionsSample()
{
return Ok();
}

[HttpPost("form")]
[Authorize]
public IActionResult PostSample([FromForm] Models.Sample model, IFormFile form)
{
return Ok();
}

[HttpGet("get")]
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
[Obsolete("test")]
public IActionResult GetDisabledSample([Required] int sample)
{
return Ok(sample);
}
}
Loading

0 comments on commit 017da0f

Please sign in to comment.