mui / material-ui

Material UI: Comprehensive React component library that implements Google's Material Design. Free forever.
https://mui.com/material-ui/
MIT License
93.3k stars 32.12k forks source link

[colorManipulator][docs] Document the color helpers #13039

Open petermikitsh opened 5 years ago

petermikitsh commented 5 years ago

Expected Behavior

I've done a comparison of various JS color utility libraries. I found that @material-ui/core/es/styles/colorManipulator.js offers the smallest bundle size of all options I could find. Here's a comparison to other libraries (all numbers are minified; second number is minified + gzipped):

Current Behavior

@oliviertassinari has stated that the color manipulator is a private API. He also openly asked if there were better open-source alternatives to the private implementation. In my view, there is no better alternative. colorManipulator.js offers basically identical functionality to all of the other libraries, and does it in the fewest amount of bytes.

Context

Color Manipulation is a very generic problem, this library has the best solution, but it is a private API. I think it could be easily publishable as a separate entity within the mono-repo structure. It's already fully unit tested, so there could be no disagreement that it would be in a good state to make publicly accessible.

oliviertassinari commented 5 years ago

At work, we are often using these helpers by tapping into the private API 🤷‍♂️. Keeping the module within a reasonable size is critical for Material-UI. In the long run, I think that moving the styles folder into a @material-ui/styles package can make sense (if we need different release lifecycle/dependencies). Should we close the issue as a duplicate of #10789? Also, I have seen some people (few) using the docs search to find more information on the color helpers without success.

@mbrookes What about keeping it where it is now?

petermikitsh commented 5 years ago

I would prefer to be able to use the color manipulator functions without having to download the entire core library. I think it would be sensible to create a @material-ui/styles package.

oliviertassinari commented 5 years ago

without having to download the entire core library.

@petermikitsh We are working on improving that overhead, but I understand the motivation: https://packagephobia.now.sh/result?p=%40material-ui%2Fcore install size.

@mbrookes What do you think of a @material-ui/styles package?

mbrookes commented 5 years ago

@oliviertassinari sure, why not. What else would you include?

Yes, it's a dupe of #10789.

petermikitsh commented 5 years ago

@oliviertassinari Besides what we've discussed here already (e.g., moving the styles directory into a separate module), is there anything else you'd like to see in a PR that could close this issue and #10789?

mbrookes commented 5 years ago

colorManipulator.js offers basically identical functionality to all of the other libraries, and does it in the fewest amount of bytes

Not strictly true - all offer varying degrees of additional functionality; somewhat proportional to their size. The exception is colorManipulator's emphasize, however, since this is the application of lighten and darken according the result of getLuminance, it could be achieved with most libraries.

colorManipulator provides the minimal subset needed for Material-UI. Still, if that's good enough for others, we should still make it a public API, as this (and other) issues suggest.

I thought it would be helpful to benchmark the function (or method) names that are used for equivalents to colorManipulator's functions, particularly for fade, which I have always found awkwardly named (fade can make a color less "faded"!).

Note that some of these functions take a relative value, e.g. lighten(color, 0.5) -> color 50% lighter than it was. While others are absolute: fade(color, 0.5) -> color with alpha set to 50%.

Library Lighten Darken Darken light / lighten dark Opacity Get luminance Get contrast ratio
Material-UI lighten darken emphasize fade getLuminance getContrastRatio
Kewler lightness (+%) lightness (-%) N/A N/A N/A N/A
Spectra lighten darken N/A fadeIn fadeOut luma N/A
tinycolor2 lighten darken N/A setAlpha getLuminance readability
color lighten darken N/A fade opaquer luminosity contrast
chroma brighten darken N/A alpha luminance contrast
polished lighten darken N/A rgba getLuminance N/A
CSS 4 color-mod proposal (removed) lightness blackness contrast alpha N/A N/A

My preference for fade is to follow tinycolor2's setAlpha, as it is descriptive, and mirrors the get of getLuminance and getContrastRatio.

I don't have a strong preference for an alternative name emphasize, however I don't think that the current name is accurate or descriptive. Suggestions welcome!

oliviertassinari commented 5 years ago

I would add polished to the list of libraries to benchmark against. I agree, setAlpha > fade. What do you think of rgba as a name suggestion?

mbrookes commented 5 years ago

polished added. Interesting that two other the libraries use fade in the function name, and that polished uses "fade" in the description fo rgba, so maybe it isn't currently so far off after all.

The only issue with rgba() is the potential for confusion with CSS rgba(), which has a different syntax.

oliviertassinari commented 5 years ago

I would add CSS, Post CSS, SASS and Less in the benchmark list. We handle the same problem https://alligator.io/css/color-function/.

mbrookes commented 5 years ago

Huh, interesting. So maybe alpha() then? Not as explicit as setAlpha(), but since it follows the future CSS naming...

oliviertassinari commented 5 years ago

So maybe alpha() then?

👍 for alpha().

petermikitsh commented 5 years ago

For "Darken light / lighten dark": contrast > emphasize, imo.

mbrookes commented 5 years ago

Darken light / lighten dark": contrast > emphasize, imo.

Sort of, but only if you were to apply a sufficiently large coefficient, and even then, the degree of contrast would be arbitrary. for example if you significantly emphasise a color that is only just on the dark side of the luminosity threshold, the contrast ratio would be much less than for the same transformation of say black, or near black.

The typical use case is to slightly lighten a dark color, or slightly darken a light color, rather than to create a contrasting color.

oliviertassinari commented 5 years ago

I was curious about the polished bundle size cost for us to use it. I couldn't get tree-shaking to work. With ES5 modules, the bundle size cost is +3 kB gzipped.

mnajdova commented 3 years ago

Going back to the original problem stated :) Now that these helpers are part of the @material-ui/system, we can go ahead and add a new page in the docs under System to document them.

jorepstein commented 2 years ago

for lazy ppl like me who end up at this page:

https://mui.com/system/basics/

samuelsycamore commented 9 months ago

Does it still make sense to take time to document these color utilities in Q4 2023, given that MUI System is set to be replaced with the zero-runtime CSS-in-JS package?