Basaingeal / Razor.SweetAlert2

A Razor class library for interacting with SweetAlert2

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support the "prefers-color-scheme" media query for themes

UweKeim opened this issue · comments

Introduction

There is a new media query prefers-color-scheme that allows a website to provide separate styles for both dark and light themes that recently is supported by most major browsers.

I'm using this for my websites heavily already with great success, especially now that iOS 13 is out that supports a dark theme, too.

Suggested Feature

My suggestion is to enhance your library to also support this, when it comes to specifying themes.

Details

Looking at this code from your readme to define a theme to use:

// Startup.cs
public void ConfigureServices(IServiceCollection services)
{
...
	services.AddSweetAlert2(options => {
		options.Theme = SweetAlertTheme.Dark;
	});
...
}

My suggestion is to enhance this in a way to be able to specify multiple themes.

I can think of something like this:

options.Theme = SweetAlertTheme.Default;
options.ThemeDark = SweetAlertTheme.Dark;

I.e. having multiple properties:

public class SweetAlertServiceOptions
{
    public SweetAlertTheme Theme { get; set; }
    public SweetAlertTheme ThemeLight { get; set; }
    public SweetAlertTheme ThemeDark { get; set; }
}

Or, as another example something like this:

options.SetTheme(ColorScheme.NoPreference, SweetAlertTheme.Default);
options.SetTheme(ColorScheme.Dark, SweetAlertTheme.Dark);

with these options.

public class SweetAlertServiceOptions
{
    public SweetAlertTheme Theme { get; set; } // Default.
    public SweetAlertTheme SetTheme(SweetAlertTheme theme); // Default, alternative.
    public SweetAlertTheme SetTheme(ColorScheme scheme, SweetAlertTheme theme);
}

The implementation could simply output all refered themes together with the media query, e.g.:

<link rel="stylesheet" id="currietechnologies-razor-sweetalert2-theme-link-1" href="_content/CurrieTechnologies.Razor.SweetAlert2/darkTheme.min.css" data-theme-number="1" media="(prefers-color-scheme: dark)">
<link rel="stylesheet" id="currietechnologies-razor-sweetalert2-theme-link-2" href="_content/CurrieTechnologies.Razor.SweetAlert2/minimalTheme.min.css" data-theme-number="2" media="(prefers-color-scheme: light)">
...

I.e. you simply iterate all set themes and output it together with the media query (if specified). This also works for browsers that do not support it if done like this.

Thanks for the issue! The prefers-color-scheme media query is something that I'm utilizing as well in some of my projects, and I agree that it works very well, especially with iOS13 and Android 10 adding dark support at about the same time.

I'll definitely look into implementing this. I have a few concerns though.

The first is that, right now the default theme is bundled into the sweetalert2 library, unlike the other themes which I pull from the @sweetalert2/sweetalert2-themes library. They do has a CSS file in the dist folder, but it includes all the styling for the library. Not just the default color scheme. So If someone were to specify say SweetAlertTheme.Dark as default, but SweetAlertTheme.Default for the light preference theme, I would be reloading all of the CSS that the library already injected into the page. Not only would this duplicate code, but say somebody had a stylesheet to override some of the default SweetAlert stylings. By adding the 'default/light' theme at the end of the header, I'd be overriding their overrides. I know the current JS library injects the styling inline, so this might already be the case even without these changes, but I'll have to look into it.

My other concern is about user clarity. I'd be worried that this could cause some confusion, and put people off of the theming option in general. For instance, with your implementation, we'd have these two enums:

enum SweetAlertTheme
    {
        Default,
        Dark,
        Minimal,
        Borderless,
        Bootstrap4
    }

and

enum ColorScheme
    {
        NoPreference,
        Light,
        Dark
    }

If you understand the role of each of these enums, no problem. But if you don't, it can be confusing. Both have a Dark option. So if I want my app to be dark, do I pick a ColorScheme.Dark or SweetAlertTheme.Dark? What's the difference between SweetAlertTheme.Default and ColorScheme.NoPreference? Here's a weird semantic thing: By calling SetTheme without a ColorScheme, you're setting a default theme, but you're not setting it to the SweetAlertTheme.Default theme. We're running into some conflation of terms which will have to be either clearly documented, or implemented in an intuitive and user friendly way. Maybe I'm not giving developers (especially cutting-edge Blazor developers) enough credit, and these concerns could be alleviated by their actual usage in the code. I just want users to feel like it's easy to jump into using different themes if they want.

All that being said, I will likely start working on this immediately, as I think it'd be a great addition and improve the flexibility a lot. Please let me know if you have any additional insights based on what I just laid out.

Thanks a lot, Michael!

I agree with your concerns. Maybe a better name for the enum could help? E.g. enum MediaQueryPrefersColorScheme instead of my initial enum ColorScheme suggestion?

Plus, how about annotating all these things with these /// doc comments to give the users nice intellisense tooltips to better understand the idea behind the methods, classes, enums, etc.?

This should be in a release later today. I'll be sure to credit you for the idea in the release and changelog.

Awesome and fast, you rock, Michael 😊.