Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Ideas for new theme/settings management#6148

JonBunator started this conversation inIdeas
Jan 15, 2023· 11 comments· 19 replies
Discussion options

I want to start a discussion about a new theme/global settings management system. I'll write down some ideas and requirements I had in mind. Please feel free to share your opinion. If you want to comment on a specific point, reference the feature like this: #F1

1. Theming

F1 Container color

Currently, we only have one primary color that is used for both primary text and primary containers. You can see this in the docs:
container2
The buttons in the middle are way too bright, imo. But we can't make them darker because then you couldn't read the primary text anymore. See button-group on the left.

M3 solves this with the introduction of separate colors for primary text and primary containers (https://m3.material.io/styles/color/overview):
container

F2 Elevation

Elevation in dark mode is still based on a dark shadow outline. It should rather change the background color.

MudBlazor:
elevation2

MUI:
elevation1

We need to support more variants of the surface color to support this feature.
This should maybe also be possible for light themes. See new m3 standard:
elvation3

F3 Inject theme-service

Many component libraries allow it to inject the theme-service into a page. This is useful if you want to change from light to dark theme.

@injectIThemeServicetheming...<MudSwitch @CheckedChanged="Change"/>publicvoid Change(booleanvalue){theming.setDarkMode(value);}

F3.1

Every color should also be accessed via the theme-service:

@injectIThemeServicetheming...theming.Palette.Primary

F4 Change colors of all components globally

The colors of all components should be able to be set via the theme. This is already partially possible. For example, there are the colorsAppbarBackground,TableLines ...

F5 Style prop

TheStyle prop adds an inline style to the component. This is not very good practice and doesn't allow the usage of CSS selectors.

<MudButtonStyle="color:red">Button</MudButton>//this will add<button style="color:red"/>

Because of that I want to try something that is also done by Emotion, styled-components etc.
A random string is generated and applied as a class selector. That selector is then used to apply the style. This allows the usage of all CSS features like hover, children-reference...

<MudButtonStyle="color:red">Button</MudButton>//this will add<button class="Aj3d03Te"/><style>.Aj3d03Te{style="color:red"}</style>

F6 Use hex colors for components

The current implementation only allows pre-selected colors to be used in components.

//This is possible<MudButtonColor="Color.Primary"/>//This is not possible<MudButton Color="#ff0000"/>

The approach explained in #F5 can be used to achieve this.
This has some advantages:

  • Fewer CSS because we don't need to add a CSS rules for every element of the Color enum
  • More customization options

Disadvantages:

  • We need to define the CSS styles for all colors inside the .cs class (imo that is not a problem if this only needs to be done for the colors)

Backwards compatibility is very important here because the Color prop is used very often. This can be achieved if we change theColor enum to a class with static props:

publicclassColor{publicstaticstringPrimary{get;}="";//<- primary color needs to be set here with functionality #F3.1...}

F7 Density system

With a density (margins/paddings) system, you should be able to set the density of all components globally. There were some efforts:#3178
But they didn't lead to anything yet

F8 Define custom theme colors

I think it's a good idea. This was rejected already in#5850
But with the implementation of #F3.1 it makes sense to have it

F9 Change material colors

The material colors should be changeable via the theme:https://mudblazor.com/features/colors#material-colors-list-of-material-colors

F12 Customize Breakpoints

It's not possible to customize the breakpoints yet.

F13 Convert themes to .json files

Converting themes to .json files (+ .json files to themes) would make it easier to save and share themes

2. Global settings

F10 SettingsService

Currently, there are many providers/services that each have their own way of handling settings:

  • Snackbar usesservices.AddMudServices
  • Dialog uses theMudDialogProvider
  • RTL uses theMudRTLProvider

Imo it makes more sense to have one provider/service that can handle all global settings and that manages the current theme.

Similar to #F3 the SettingsService should also be injectable into pages to change specific settings everywhere in the application.
In #F3 I mentioned a IThemeService. It should be discussed if we should serve the theme via the settings service or if a separate approach is better.
ISettingsService.Theme instead ofIThemeService?

F11 Change default prop values of components

It should be possible to change the default values of properties. For example, MudTextField has the default variantVariant.Text. The default value should be changeable.
This could be done using Source Generators. For every class, we generate a settings class based on the props that should be changeable.
For example, this class:

publicpartialclassMudButton:MudBaseButton{  .../// <summary>/// The variant to use./// </summary>[Parameter][SettingsProp][Category(CategoryTypes.Button.Appearance)]publicVariantVariant{get;set;}=Variant.Text;  ...}

will generate the following settings class:

publicclassMudButtonSettings{publicVariantVariant{get;set;}=Variant.Text;}

Then you can change the default value in the settings provider:

MudSettingss=newMudSettings(){MudButtonSettings=MudButtonSettings(){Variant=Variant.Text}}
You must be logged in to vote

Replies: 11 comments 19 replies

Comment options

I'm sure I'll have more later, but I really like the idea presented in F11.

Changing default prop values to be configurable site wide. It would clean up a lot of standard things and make writing components a bit quicker.

I do wonder if it will be easily overridable. I've had some issues with IDialogProvider not accepting local overrides from near where they're called.

You must be logged in to vote
3 replies
@JonBunator
Comment options

JonBunatorJan 16, 2023
Maintainer Author

I'm sure I'll have more later, but I really like the idea presented in F11.

Changing default prop values to be configurable site wide. It would clean up a lot of standard things and make writing components a bit quicker.

It would also allow us to localize components better.

I do wonder if it will be easily overridable. I've had some issues with IDialogProvider not accepting local overrides from near where they're called.

That's a good question. The settings service would just set new values in the constructor. I don't think that's a problem. But we'll have to see

@Omnideth
Comment options

I would like to elaborate, now, and say that after a second/third look over of these I think I'm in favor of most of them.

The ones that REALLY make me excited are F1, F2, F3 (& 3.1), F5, F8 (listed two different times, for two different purposes, I mean F8 the former - about defining Custom theme colors), F10, and F11.

I know that's most of them, whatever.

F1 I simply like, I think it'd be a good addition.

F2 I think looks amazing the way MUI does it, if that's something possible, I can't see any drawback. I don't have any big problems with how Elevation shadows look now, but I do admit the MUI look seems cleaner and draws focus better than just the shader outside the element. This might be a personal preference thing, though.

F3, 3.1 are very nice ideas that I think would be great. I believe getting a ThemeService would be great as a moving implementation and allows for some more direct interaction with the theme when needed. It seems a bit niche as /is/, but I believe it expands the possibilities going forward. I believe this might be a way to hook into the MudThemes somehow as well, by injecting a theme on Startup, maybe from a json config instead of in code, allowing you to be able to export your theme from MudTheme and bundle it in your project and easily swap them out? I think that would be a pretty neat way to integrate it on load, which is separate from the portable use cases of just having the values available when you're coding to utilize portions of the theme in non default ways.

F5 I think would be nice to have, though I don't know how it would feel - as in, where does the .css get generated and when? Upon build?

F8 (custom colors F8, not the other) I think would be great to have some sort of... mutable collection of key values that you could add to in the ThemeService that lets you store custom colors to retrieve as needed with your own names. I think that would be neat, potentially useful.

F10 I think I like the idea of a SettingsService housing the IThemeProvider as you mention here, but I would wonder what other settings you'd want to expose. Would this roll into F11's implementation of basically adding theming to components? Would that be considered a SettingsService or still, thematically, just an IThemeProvider?

Speaking of, F11 just seems like it will save so much time typing the same 2 or 3 Key=Value combinations on some high use component types. Since the general theme of the whole website often uses a ton of the same basic setup for TextField / Button etc. I think F11 is my favorite single change of the whole list.

Hopefully some of the above is useful.

@JonBunator
Comment options

JonBunatorJan 19, 2023
Maintainer Author

Thanks a lot for your detailed feedback!
F2 is also a material 2 standard. Seehttps://m2.material.io/design/color/dark-theme.html#properties
Actually a pretty nice way of doing it with a white transparent overlay

injecting a theme on Startup, maybe from a json config instead of in code

That's another good idea. I think you can pretty easily convert json to C# objects. I'll add it to the list as #F13

F5 I think would be nice to have, though I don't know how it would feel - as in, where does the .css get generated and when? Upon build?

The theme service will collect all styles from all components and then generate a single<style> block.
The css is generated every time a style changes. We have to see if it's worth performance wise. But inline styles are generally worse at performance. So maybe it could be even faster

F10 I think I like the idea of a SettingsService housing the IThemeProvider as you mention here, but I would wonder what other settings you'd want to expose. Would this roll into F11's implementation of basically adding theming to components? Would that be considered a SettingsService or still, thematically, just an IThemeProvider?

Dark theme change, RTL, themes and all default values of the components. We'll have to see if the default values should rather be part of the theme or not

Ahh I used F8 twice. I'll rename it to F12. I hope it's not too confusing

Comment options

These are some really good points.

Currently, there are many providers/services that each have their own way of handling settings:

Snackbar uses services.AddMudServices
Dialog uses the MudDialogProvider
RTL uses the MudRTLProvider
Imo it makes more sense to have one provider/service that can handle all global settings and that manages the current theme.

Similar to #F3 the SettingsService should also be injectable into pages to change specific settings everywhere in the application.
In #F3 I mentioned a IThemeService. It should be discussed if we should serve the theme via the settings service or if a separate >approach is better.
ISettingsService.Theme instead of IThemeService?

The struggles of getting the value from the currentIsDarkMode.
If only there was a scoped service from which you could get the value.

You must be logged in to vote
1 reply
@JonBunator
Comment options

JonBunatorJan 16, 2023
Maintainer Author

Exactly, that was the idea. At the moment, you have to create your own service that handles darkmode changes etc.

Comment options

F8, F9 I think.
Until browsers will widely adoptCSS Relative Color Syntax it would be very helpful if all base colour variables would be defined as a rgb composable values and not final colours. If I would like for example make--mud-palette-error: #f64e62ff; more transparent I have no other option but to overwrite the variable. With proposed change I would be able to reuse the base colour.

Current

:root {--mud-palette-error:#f64e62ff;}.mud-alert-filled-translucent {background-color:var(--mud-palette-error);}.mud-alert-filled-error-translucent {/* the best I can do to add transparency is this */background-color:#f64e627f;}

Proposed

:root {--mud-palette-error:2467898;}.mud-alert-filled-error {background-color:rgb(var(--mud-palette-error)/1.0);}.mud-alert-filled-error-translucent {background-color:rgb(var(--mud-palette-error)/0.5);}
You must be logged in to vote
10 replies
@JonBunator
Comment options

JonBunatorJan 29, 2023
Maintainer Author

Hmm, that's also a good idea. But that would double our css variables of course

@BieleckiLtd
Comment options

My suggestion is no longer valid I think. I just realized all palette colours are defined in the code, not CSS. That means they can be modified or derived on runtime as needed. If anyone is wondering how:

@usingMudBlazor.Utilities;@injectLayoutService LayoutService@code{MudColormyDerivedColor;voidSetMyDerivedColor(){varbaseColor=LayoutService.CurrentTheme.Palette.Primary;myDerivedColor=newMudColor(baseColor.Value).SetAlpha(70);}}
@JonBunator
Comment options

JonBunatorJan 29, 2023
Maintainer Author

@using MudBlazor.Utilities;@inject LayoutService LayoutService @code {    MudColor myDerivedColor;    void SetMyDerivedColor()    {        var baseColor = LayoutService.CurrentTheme.Palette.Primary;        myDerivedColor = new MudColor(baseColor.Value).SetAlpha(70);    }}

That's exactly what a meant withOr with F8 it might be not required because then you could just define the color opacity version you need

My suggestion is no longer valid I think. I just realized all palette colours are defined in the code, not CSS.

They are converted to css variables and applied inside a<style>. So, I think it's possible

@BieleckiLtd
Comment options

Agree. F8 was a good idea.

@tstockwell
Comment options

I know that I'm late to the party but I couldn't resist replying since I've recently solved this same problem for myself.
My solution to changing the alpha of hex colors uses the color-mix function like so...

:root {  --mud-palette-error: #f64e62ff;}.mud-alert-filled-translucent {    background-color: var(--mud-palette-error);}.mud-alert-filled-error-translucent {  background-color: color-mix(in_srgb, transparent 80%, var(--mud-palette-error) 20%);}

I'm also able to make the alpha percentage a CSS variable.

Comment options

One suggestion: Support Multiple Themes

Yes we can change the theme dynamically, but we can't use 2 themes at the same time.

If we remove the popoverprovider in theme provider and give a selector parameter, we can simply use multiple themes with css classes, like

You must be logged in to vote
1 reply
@TDroogers
Comment options

Yes, and with#6519 it is possible to make a sub theme by inheriting your base theme with only some changes but keeping it in sync with your base theme for all other settings.

Comment options

Right now I'm starting a new project and have been given a palette to have the UI use. I've fallen at the first hurdle because I cannot specify a colour for the hover state of the MudButton. The solutions I've found here involve complicated hacks. So a solution that provides anyone to customise the theme fully would be good from my point of view, and some of the above look great.

I can see there are conflicts in some too - a comprehensive container for all theme elements would need to be flexible enough to handle new components in future, so probably use a dictionary. The idea of a component specific attribute to specify the theming allows great flexibility, but then means lots of individual classes to manage. I very much like the .json file option as it makes editing easier. It could also be automatically updated as components reference it, so that it grows automatically to fit the components used.

One thought I did have was that a theme customiser could have a default so that you set the primary color, and then from that is derived the hover color via an opacity setting, as now. But if I wanted to override that, then I could set a specific hover color, and that then gets used.

So while I don't know which is the best option, I very much endorse the idea of improving the theme management, and comprehensively please to handle more than it does now.

You must be logged in to vote
1 reply
@mj2015
Comment options

I had a further thought - if the theme manager is to be a repository that is organised by a dictionary of class names, like "MudButton" then a useful addition would be to have the MudButton type have a "CustomTheme" property so that it could use the "MudButton-{CustomTheme}" dictionary element to see if there is customisation for that button. This would allow users to have a general property set in the theme for MudButton, but also have CustomTheme="bluebutton" properties to make for easy centrally controlled styling.

Comment options

Ad F10, the global settings service would also be the perfect place for I18N strings so users can change everything that is currently hard-coded to English.

You must be logged in to vote
0 replies
Comment options

I really like the proposal of taking inspiration from Emotion and other CSS in js solutions, but I have one question: Does this solution require inline styles (or writing <style> tags with CSS to the DOM)?

If this proposal does involve writing inline styles OR writing <style> tags to the DOM dynamically, it will be really difficult to combine with a Content Security Policy without using "unsafe-inline" (or at "best" "unsafe-hashes"). These are both to be avoided. Ref discussion in issue#4529

A solution to this could be to use a module bundler to extract these styles to a separate stylesheet.

You must be logged in to vote
0 replies
Comment options

It's great, if you can implement app bar with centered nav-links and square corner components.
image

You must be logged in to vote
0 replies
Comment options

As a suggestion of density suggestion, we can define 4 kind of density: "Standard, Comfort, Slim and SuperSlim"

Standard has 8px padding, Comfort 4px, Slim 2px and none for SuperSlim. Component's height should reduce in slim and SuperSlim also.

You must be logged in to vote
1 reply
@BieleckiLtd
Comment options

I often require a higher level of density than what is currently considered 'dense', especially when working with tabular data. However, using 0px padding never looks good IMO. Excel-like padding and row/column sizing is usually compact enough to strike a good balance between readability and the amount of data on the screen.

Comment options

These ideas are very good, any plans for them to be implemented?

You must be logged in to vote
0 replies
Comment options

ingkor
Oct 23, 2024
Collaborator

Tag for myself to work on this tomorrow.
@henon could I get your guidance on the required changes.

You must be logged in to vote
2 replies
@henon
Comment options

I would change the priority of F6 low. I am still thinking it would be cool to have it but many team members think it is not worth the effort. Maybe if we find a volunteer who wants to implement it all and can show on one component that it doesn't increase component complexity all that much then we might still have it.

F11 is partially done. I would promote it to highest priority and see which other defaults we should make configurable.

We should add another point F12 to find a way to inject theme styles and other dynamic styles in a CSP-compliant manner, i.e. with a custom endpoint like@meenzen suggested. Or a source generator (where applicable), or any other way if anybody has better ideas.

That is essentially it. All the other points seem to be still valid. The team should discuss and agree on priorities for all the points.

@Kevinf63
Comment options

I would change the priority of F6 low. I am still thinking it would be cool to have it but many team members think it is not worth the effort. Maybe if we find a volunteer who wants to implement it all and can show on one component that it doesn't increase component complexity all that much then we might still have it.

F11 is partially done. I would promote it to highest priority and see which other defaults we should make configurable.

We should add another point F12 to find a way to inject theme styles and other dynamic styles in a CSP-compliant manner, i.e. with a custom endpoint like@meenzen suggested. Or a source generator (where applicable), or any other way if anybody has better ideas.

That is essentially it. All the other points seem to be still valid. The team should discuss and agree on priorities for all the points.

Was F11, "Change default prop values of components" ever delivered? Was looking to distribute a NuGet package of our defined Theme and was wondering if style variants are covered nowadays?

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Category
Ideas
Labels
None yet
14 participants
@JonBunator@henon@tstockwell@Omnideth@Kevinf63@mj2015@SKIDDOW@ingkor@TDroogers@rafaelparenza@BieleckiLtd@Tyme-Bleyaert@mckaragoz@sigurdmwahl

[8]ページ先頭

©2009-2025 Movatter.jp