-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Theme] Inadeguate palette theming primitives #8075
Comments
I have been maturing the reflexion about this issue. I think that it should be handled at the configuration time of the palette. We have a small section about it in the documentation. I like that idea of exposing a palette generation tool, however, it comes with a bundle size challenge. This should be a static tool, I don't want to bloat the bundle with something outputting a small object. Also, this palette generation tool doesn't have to be scoped to Material-UI. In a way, I do think that our best solution going forward is a competitor to one of the linked projects in the documentation. This is not something I want to put my energy one, but It can be a good marketing tool, as well as a wahoo effect if we add a demo in the documentation (something more powerful than the light/dark dynamic theme switch). |
A demo would also be the occasion to fix #2009. |
This is an issue I completely underestimated. I think we can split the problem in two then:
What scares me is that when extracting a color from the theme components usually access a specific shade of a hue. But I believe this is not in spec. As far as I understood the spec, the hues are reference material to choose colors from, it is not a framework to define the colors of an application. In flow terms: type Shade = string; // #RRGGBB
type Hue = {
50: Shade,
100: Shade,
// ...
900: Shade,
A100: Shade,
A200: Shade,
A400: Shade,
A700: Shade
};
type PaletteColor = {
main: Shade,
lighter: Shade,
darker: Shade
};
type Palette = {
type: 'light' | 'dark',
primary: PaletteColor,
accent: PaletteColor
};
type Theme = {
// ...
palette: Palette
}; |
I have been noticed the opposite on the specification, for instance with the button:
So, as far as I see the issue. It's mainly a matter of addressing point number 1. Then regarding point number 2. I can share the usage frequency on the codebase: primary
secondary
error
|
Actually, looking at the source code of material-components-web. I think that we should try to simplify the situation! This would help a lot with point n°1 as we would be able to guide people toward the official color tool |
Following up on #8383, I've been porting a large app to I was expecting something similar to what material-components-web are doing, provide my main colors, and then the library figures the rest out. I went through the tools to create my 3 palettes but ended up not getting the colors I wanted on most of the UI elements. If you want to quickly get going and immediately have a theme corresponding to your brand it is currently pretty hard. For example: If I want my primary buttons to be pure |
Well, I'm gonna share my experience (used this lib in 3 projects so far):
If I didn't do this, I have to use the override system and change every color of every component... Sorry for bad english. |
I also stumbled upon this issue. I used mdl long time ago, lastly I tried material-component-web. So I really hope this will change. I was just convinced to use material-ui until I came across this issue. |
@vuhrmeister, don't diss the lib just for this. The quality of the abstractions here over shines this issue, even if important. |
@yuchi well, I don't blame the whole lib just due to that single issue. It's not by chance that I chose material-ui over the competitors ;) |
Sorry it sounds harsher than I expected! Didn't mean to suggest that, just wanted to minimize the gravity of this issue 😅 |
@oliviertassinari Wouldn't it be possible to implement this in a non-breaking way? E.g. |
The previous sentence has a chance of being misinterpreted into 'overriding the primary *palette*, entirely with a particular *hue*'. Reader might confuse the terms Hue, Palette and Colors by this sentence, even though they were explained just above. (A slight reference here : mui#8075)
Alright, let's fix this issue. It's going to be a breaking change. But I think that it's important to simplify the situation. I have been giving a look at how Bootstrap and material-components-web palette work. We can try to copy what works best for them. Here is my proposal: The new APIimport { createMuiTheme } from 'material-ui/styles';
import indigo from 'material-ui/colors/indigo';
import pink from 'material-ui/colors/pink';
import red from 'material-ui/colors/red';
import { darken, lighten } from 'material-ui/styles/colorManipulator';
const themeDefault = createMuiTheme()
// All the following keys are optional.
// We try our best to provide a great default value.
// The following values illustrate the default logic when our users don't provide anything.
const theme = createMuiTheme({
palette: {
contrastThreshold: 3.1,
tonalOffset: 0.07,
primary: {
// Looking at material-components-web,
// lighten() and darken() might not be enough:
// https://github.com/material-components/material-components-web/blob/ac46b8863c4dab9fc22c4c662dc6bd1b65dd652f/packages/mdc-theme/_functions.scss#L83
light: lighten(indigo[500], 0.07),
main: indigo[500],
dark: darken(indigo[500], 0.07),
contrastText: themeDefault.palette.getContrastText(indigo[500]),
},
secondary: {
light: lighten(pink.A400, 0.07),
main: pink.A400,
dark: darken(pink.A400, 0.07)
contrastText: themeDefault.palette.getContrastText(pink.A400),
},
error: red.A400,
},
}); The upgrade pathconst theme = createMuiTheme({
palette: {
- primary: indigo,
+ primary: {
+ light: indigo[200],
+ main: indigo[500],
+ dark: indigo[700],
},
- secondary: pink,
+ secondary: {
+ light: pink.A200,
+ main: pink.A400,
+ dark: pink.A700,
},
- error: red,
+ error: red.A400,
},
}); Problems solved
|
I'm liking this overall, it combines a number of the options we've discussed for various problems into a cohesive whole. Two thoughts:
|
@mbrookes I think so. It's not just about the Material Design specification. As far as I have looked at the SASS files of material-web-components, they almost don't use the tones. It's more about providing to users a visual chromatic hierarchy set they can use. It's very common to have designers working with different tones (based on the different projects I have been working on), often 3-5.
This breaking change should be easily handled by the users. What's the point of making the upgrade path simpler? It will cost people how upgraded bundle size. |
Looks good. It'd be great if we can also only provide the |
@Floriferous That's the intention (or rather, that's what the code already does 😄 ). |
@oliviertassinari: if this covers the spec, it would be awesome. @mbrookes: we need to ship color parsing/manipulation functions then… |
@yuchi For example? |
I probably misinterpreted your comment. Did you mean to automatically infer |
It does, if you provide main, but omit light and/or dark.
For example? PS. Sorry, about the noise. Made the mistake of referencing a comment here from the PR, and as I"ve been fighting the CI gods, it's been spamming this issue. |
* [core] Revise the theme.palette.primary & secondary approach #8075 (comment) Closes 8075 * Revise the theme.palette.primary & secondary approach * Update & expand createPalette tests * Update createMuiTheme tests * colorManipulator refactoring * Bump package size
Problem Description
While customizing the library with a custom theme I found the way we have to specify the
primary
andaccent
shades a little bit controversial. Let me explain this a little bit more thoroughly.Material Design guidelines define a set of “colors” (or “hues”) beautifully crafted by the Google Design team so that each “color” has a nicely defined set of shades (
50
,100
to900
). Once you choose your main starting shade inside the hue, moving up and down helps in creating a visual chromatic hierarchy. Given the length of jumps required to have enough contrast inside the hue, and to give more vibrancy to the design of apps, they suggest to start at500
and move up and down from there.But nothing stops you from choosing a different shade as your starting point.
In fact these screenshots have been generated by the “official” Color Tool.
The actual problem
In this library when defining the theme for the application we can specify the hue for primary or accent colors, but not the specific shade we want.
To do so we need to create a custom “color” by shifting values up or down in order to move the selected shade to the
500
(andA500
) position.And most of the time this is required for the UI to have some chromatic sense. If you look at the documentation itself you can find an occurrence of a wrongly defined color right in the «Themes» section.
In fact this approach makes it difficult for components to extract the right colors.
Proposal
It’s a little but late to change this part of the library but I believe something should be done about it; be it an utility to create new colors automatically based on a shade (
shiftColor(greeen, 900)
) or a different approach.The text was updated successfully, but these errors were encountered: