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 😊.