microsoft / fluent-ui-react

An ecosystem for building highly customizable enterprise class user interfaces.
https://aka.ms/fluent-ui
MIT License
432 stars 55 forks source link

Create siteVariables palette interface with color names #423

Closed alinais closed 5 years ago

alinais commented 6 years ago

Feature Request

Problem description

Each component should have the ability to change its color through the color prop. The color value should be available as part of a predefined palette.

Proposed solution

Create siteVariables palette interface with color names.

[Fork, update, and replace this pen if you can show the proposed solution]: https://codesandbox.io/s/2l3n74j9y

layershifter commented 6 years ago

Should we use the SUI palette there?

https://semantic-ui.com/usage/theming.html#sitewide-defaults

[
  'primary',  'secondary',

  'red', 'orange', 'yellow', 'olive', 'green', 'teal', 'blue', 'violet', 'purple', 'pink', 'brown', 'grey', 'black'
]

Should we also add a white color?

levithomason commented 6 years ago

🌟 Criteria

We should define our criteria for a good color palette so we know what we're aiming for. An artists palette is quite different from the Material Color System, for example. This is because their goals are completely different.

We might have some goals like this for starters:

Resources

Let's consider more information before suggesting a palette.

Natural Language Colors

There is a lot of mind blowing research on the development of color names in natural language around the globe. Take 6min to watch "The surprising pattern behind color names around the world ".

The short of it is that cultures develop words for specific areas of the spectrum in a predictable order, regardless of their language. We first identify black, white, and red. Then as the language develops, yellow and green, etc. Example, English has 11 main color words but Russian has 12:

image

This eventually produced the World Color Survey to determine how humans classify colors. I think the test of 2,600 languages, 110 countries, and several thousands of generations is a strong basis to start with. Humans have take a very long time to come up with the words that are most helpful in communicating color, we should pay very close attention to the color ranges of these words across the worlds most influential languages.

Design & Engineering

Though design guides and frameworks have hardly existed at all compared to natural language, we can at least look at the most useful and influential design guides and frameworks to see what they have done. Try https://styleguides.io as a starting point for finding guides and frameworks.

We should also compile a list of guides and frameworks that we deem reputable and useful references for these kinds of decisions.

Color wheel

Artists have also been trying to figure out the most useful palette of colors for as long as humans have been creating imagery. We should take a look at these sources as well: https://en.wikipedia.org/wiki/Color_wheel

It is worth noting that there are also several versions of the color wheel based on different methodologies such as artistic, pigment color, spectral color, etc.

Conclusion

Someone should touch up the criteria proposed, catch up on these resources, do some basic comparative analysis, and propose a potentially most ideal color palette.

layershifter commented 6 years ago

Common UI frameworks

Bootstrap, colors

Palette | Color | Value | | :-: | :-: | | `Blue` | `#007bff` | | `Cyan` | `#17a2b8` | | `Green` | `#28a745` | | `Indigo` | `#6610f2` | | `Orange` | `#fd7e14` | | `Pink` | `#e83e8c` | | `Purple` | `#6f42c1` | | `Teal` | `#20c997` | | `Red` | `#dc3545` | | `Yellow` | `#ffc107` | | Color | Value | Alias | | :-: | :-: | :-: | | `Primary` | `#007bff` | `$blue` | `Secondary` | `#6c757d` | `$gray-600` | `Success` | `#28a745` | `$green` | `Info` | `#17a2b8` | `$info` | `Warning` | `#ffc107` | `$warning` | `Danger` | `#dc3545` | `$danger` | `Light` | `#f8f9fa` | `$light` | `Dark` | `#343a40` | `$dark`

Bulma, colors

Palette | Color | Value | | :-: | :-: | | `Black` | `hsl(0, 0%, 4%)` | | `Dark` | `hsl(0, 0%, 21%)` | | `Danger` | `hsl(348, 100%, 61%)` | | `Light` | `hsl(0, 0%, 96%)` | | `Link` | `hsl(217, 71%, 53%)` | | `Info` | `hsl(204, 86%, 53%)` | | `Primary` | `hsl(171, 100%, 41%)` | | `Success` | `hsl(141, 71%, 48%)` | | `Warning` | `hsl(48, 100%, 67%)` | | `White` | `hsl(0, 0%, 100%)` |

Foundation, colors

Palette | Color | Value | | :-: | :-: | | `Alert` | `#cc4b37` | | `Black` | `#0a0a0a` | | `Dark Gray` | `#8a8a8a` | | `Light Gray` | `#e6e6e6` | | `Medium Gray` | `#cacaca` | | `Primary` | `#1779ba` | | `Secondary` | `#767676` | | `Success` | `#3adb76` | | `Warning` | `#ffae00` | | `White` | `#fefefe` |

Semantic UI, colors

Palette | Color | Value | | :-: | :-: | | `Black` | `#000000` | | `Blue` | `#0E6EB8` | | `Brown` | `#A52A2A` | | `Green` | `#016936` | | `Grey` | `#A0A0A0` | | `Olive` | `#32CD32` | | `Orange` | `#FE9A76` | | `Pink` | `#FF1493` | | `Purple` | `#B413EC` | | `Red` | `#B03060` | | `Teal` | `#008080` | | `Violet` | `#EE82EE` | | `Yellow` | `#FFD700` | | Color | Value | Alias | | :-: | :-: | :-: | | `Primary` | `#0E6EB8` | `$blue` | `Secondary` | `#000000` | `$black`

Tailwind CSS, colors

Palette | Color | Value | | :-: | :-: | | `Blue` | `#3490DC` | | `Grey` | `#B8C2CC` | | `Green` | `#38C172` | | `Indigo` | `#6574CD` | | `Orange` | `#F6993F` | | `Pink` | `#F66D9B` | | `Purple` | `#9561E2` | | `Red` | `#E3342F` | | `Teal` | `#4DC0B5` | | `Yellow` | `#FFED4A` |

Turret CSS, colors

Palette | Color | Value | | :-: | :-: | | `Black` | `#000000` | | `Dark` | `#323236` | | `Error` | `#D91E18` | | `Grey` | `#616166` | | `Info` | `#1E90FF` | `Light` | `#D3D3D9` | | `Primary` | `#3455DB` | | `Secondary` | `rebeccapurple` | | `Success` | `#00AA00` | `Tertiary` | `#8B008B` | | `Warning` | `#FF4500` | `White` | `#FFFFFF` |

Others

layershifter commented 6 years ago

Corporate UI frameworks

Atlassian design, colors

Palette | Color | Value | | :-: | :-: | | `Blue` | `#0747A6` | | `Green` | `#006644` | | `Purple` | `#403294` | | `Red` | `#BF2600` | | `Teal` | `#008DA6` | | `Yellow` | `#FF8B00` |

Carbon by IBM, colors

Palette | Color | Value | | :-: | :-: | | `brand-01` | `#3d70b2` | | `brand-02` | `#5596e6` | | `brand-03` | `#41d6c3` | | `ui-01` | `#ffffff` | | `ui-02` | `#f4f7fb` | | `ui-03` | `#dfe3e6` | | `ui-04` | `#8897a2` | | `ui-05` | `#5a6872` | | `text-01` | `#152935` | | `text-02` | `#5a6872` | | `text-03` | `#cdd1d4` | | `inverse-01` | `#ffffff` | | `inverse-02` | `#272d33` | | `field-01` | `#f4f7fb` | | `field-02` | `#ffffff` | | `hover-primary` | `#30588c` | | `hover-primary-text` | `#294c86` | | `hover-danger` | `#bd1427` | | `hover-secondary` | `#3d70b2` | | `hover-row` | `rgba(85,150,230,.1)` | | `support-01` | `#e0182d` | | `support-02` | `#5aa700` | | `support-03` | `#efc100` | | `support-04` | `#5aaafa` |

Lightning Design System by Salesforce, colors

Palette | Color | Value | | :-: | :-: | | `Gray 1`| `#fff` | | `Gray 2`| `#fafaf9` | | `Gray 3`| `#f3f2f2` | | `Gray 4`| `#ecebea` | | `Gray 5`| `#dddbda` | | `Gray 6`| `#c9c7c5` | | `Gray 7`| `#b0adab` | | `Gray 8`| `#969492` | | `Gray 9`| `#706e6b` | | `Gray 10` | `#514f4d` | | `Gray 11` | `#3e3e3c` | | `Gray 12` | `#2b2826` | | Color | Value | | :-: | :-: | | `Accessible` | `#0070d2` | | `Accessible - Active` | `#005fb2` | | `Contrast` | `#1a1b1e` | | `Contrast - Active` | `#0d0e12` | | `Dark` | `#182337` | | `Dark - Active` | `#253045` | | `Light` | `#f4f6fe` | | `Light - Active` | `#e3e5ed` | | `Primary` | `#1589ee` | | `Primary - Active` | `#007add` |

Fabric, colors

Palette | Color | Value | | :-: | :-: | `PinkRed` | `#750b1c` `Red` | `#d13438` `RedOrange` | `#da3b01` `Orange` | `#ffaa44` `Yellow` | `#fce100` `OrangeYellow` | `#c19c00` `YellowGreen` | `#8cbd18` `Green` | `#498205` `GreenCyan` | `#00ad56` `Cyan` | `#00b7c3` `CyanBlue` | `#0078d4` `Blue` | `#4f6bed` `BlueMagenta` | `#8378de` `Magenta` | `#c239b3` `MagentaPink` | `#e3008c` `Gray` | `#a0aeb2`

Primer by Github, colors

Palette | Color | Value | | :-: | :-: | | `Black` | `#1b1f23` | | `Blue` | `#0366d6` | | `Gray` | `#6a737d` | | `Green` | `#28a745` | | `Orange` | `#f66a0a` | | `Purple` | `#6f42c1` | | `Red` | `#d73a49` | | `White` | `#fff` | | `Yellow` | `#ffd33d` |

Proton by Fifefox, colors

Palette | Color | Value | | :-: | :-: | | `Blue` | `#0a84ff` | | `Green` | `#30e60b` | | `Grey` | `#737373` | | `Ink` | `#363959` | | `Magenta` | `#ff1ad9` | | `Orange` | `#ff9400` | | `Purple` | `#9400ff` | | `Red` | `#ff0039` | | `Teal` | `#00feff` | | `White` | `#ffffff` | | `Yellow` | `#ffe900` |

Others

layershifter commented 6 years ago

I've analyzed a little ton of stuff, let's summarize it. I will take numbers from community frameworks because the most of corporate frameworks doesn't work with natural color names.

Natural vs state

Type Points Frameworks
State 3 Bulma, Foundation, Turret CSS
Natural 3 Bootstrap, Semantic UI, Tailwind CSS
--- ---
Aliases for state 2 Bootstrap, Semantic UI

Usage of natural color names in palettes

Color Points Framework
Black 3 Bulma, Foundation, Semantic UI, Turret CSS
Blue 3 Bootstrap, Semantic UI, Tailwind CSS
Brown 1 Semantic UI
Cyan 1 Bootstrap
Green 3 Semantic UI, Bootstrap, Tailwind CSS
Grey 2 Semantic UI, Tailwind CSS
Olive 1 Semantic UI
Indigo 2 Bootstrap, Tailwind CSS
Orange 3 Bootstrap, Semantic UI, Tailwind CSS
Pink 3 Bootstrap, Semantic UI, Tailwind CSS
Purple 3 Bootstrap, Semantic UI, Tailwind CSS
Teal 3 Bootstrap, Semantic UI, Tailwind CSS
Red 3 Bootstrap, Semantic UI, Tailwind CSS
Violet 1 Semantic UI
White 2 Bulma, Foundation, Turret CSS
Yellow 3 Bootstrap, Semantic UI, Tailwind CSS

primary & secondary

Color Points Frameworks
Primary 5 Bootstrap, Bulma, Foundation, Semantic UI, Turret CSS
Secondary 4 Bootstrap, Foundation, Semantic UI, Turret CSS

grey vs gray

Color Points Framework
Grey 4 Bulma, Semantic UI, Tailwind CSS, Turret CSS
Gray 2 Bootstrap, Foundation
layershifter commented 6 years ago

Summary

  1. We should have the predefined palette of colors.
  2. The palette should be easily extendable.

Proposed palette

I've picked colors from summary table that have >= 2 points.

Name Color
Black #252423 (taken from Teams theme)
Blue ?
Green #92C353 (taken from Teams theme)
Grey ?
Orange #CC4A31 (taken from Teams theme)
Pink ?
Purple ?
Teal ?
Red #C4314B (taken from Teams theme)
White #FFFFFF (taken from Teams theme)
Yellow #F8D22A (taken from Teams theme)

More colors

Some frameworks provide more colors in their palette, there are common patterns:

However, I'm not sure that these colors should be a part of the default theme.

Others

layershifter commented 6 years ago

I've tried to dogfood some ideas in #451. You can pull the branch and try it:

Preview ![image](https://user-images.githubusercontent.com/14183168/48197620-f7493080-e35e-11e8-8d2b-b88ccb39167d.png)

Base/Core/YOUR_NAME colors

White and black colors can't have a palette, what will be darker than #000000? Or lighter than #ffffff? It will be confusing. However, it's reasonable to allow define black and white colors, even Teams use #252423 as black.

Proton also separate white color. But, I should note that Primer has fades for white and black colors. I'm not sure that it's the best idea.

type BaseColors = {
  black: string
  white: string
}

Natural colors

The idea above changes the core palette a little. In #451 I used colors from Proton. This gives us 9 colors which are presented by the NaturalPalettes type.

Color Value
Blue #0060df
Green #12bc00
Grey #4a4a4f
Orange #d76e00
Pink #ed00b5
Purple #8000d7
Teal #00c8d7
Red #d70022
Yellow #d7b600

Each color is presented by its palette, each palette contains 7 gradients of colors: lightest, lighter, light, base, dark, darker, darkest. All of these is defined in the ColorPalette type.

(!) I've decided to go with semantic names, just compare colors.red.100 vs colors.red.lightest. However, this doesn't fit needs of Teams which has 8 colors in brand.

A palette for a color can be filled manually of by util:

const naturalPalettes: NaturalPalettes = {
  blue: createPalette(__BASE_COLOR__),
  green: {
    lightest: _VALUE_,
    lighter: _VALUE_,
  }

State colors

We decided to go with primary (i.e. brand) and secondary colors, however I think that this palette should be increased with info, positive/success, negative/error, warning. The easiest case where these colors can be needed is Message or Form component. These colors are also defined in Bulma and Bootstrap for example.

I also think that we need a separate palette for text like this done in Alfabank Styleguide, it's not correct to use grey color for text. For example, a disabled or timestamp variations for text.

State colors can be just aliases for natural colors:

  info: naturalPalettes.blue,
  positive: naturalPalettes.green,
  negative: naturalPalettes.red,
  warning: naturalPalettes.yellow,
layershifter commented 5 years ago

The final decisions that will go to RFC.


Naming

1. PrimitiveColors

Includes only white and black that are will be represented by the string type.

2. NaturalColors

Will include 9 colors (blue, green, grey, orange, pink, purple, teal, red, yellow) as we decided before, each color should implement the ColorVariants type.

3. ContextualColors

We decided to go with ContextualColors instead of StateColors because it's more intuitive. This type will include: primary, secondary, text, danger, info, success, warning.

ColorPalette

All color types are unioned to the ColorPalette which will be exported. Names of types can be changed if we will find out a better name.

Utils

createPalette()

This util will create a color from a passed base color.

unsupportedColorVariants(), unsupportedColor()

These utils will throw a warning if you will try to access to a color or a variant that it is not supported by your theme.

Variants

We decided to go with numeric values instead of semantic, the main advantage this gives us more colors (10 vs 7) that will fit all out needs. The second reason - this pattern is widely used (Material, Proton, etc.)

Teams

We had a color palette that matches the described design. So, it's not a problem.

Complaisance

(!) We decided that every theme should implement our palette interfaces. For simplication we have utils that allow to block usage of colors or simply generate them.

Types and utils will be placed in the default theme.


We will get an initial implementation on this week.

kuzhelov commented 5 years ago

Have thoroughly reviewed the discussion, have several questions that would like to clarify:

Material UI approach is not included in stats

For some reason Material UI Color System is not covered in the stats - at the same time, they provide one of the most comprehensive reviews on this topic. Frankly, was surprised a bit with that.

'On' colors (for text, icons, other content..)

Here, in the RFC, a topic of 'on' colors is not covered - i.e. content colors (of text, icons, etc) that will be displayed on primary or secondary background. Note that this aspect is a basic one for most theming approaches, as it is a key factor for accessible data presentation (consider a case where, for example, one would need to provide different text color which is dependent on whether lightest or darkest tint of primary color is used - as it is not possible to just use single, say, black color for both cases). What are the actions planned to address that?

Note that this is quite important topic from accessibility perspective, as this question is one of the key that defines whether app's content will be accessible or not, according to WCAG accessibility rating of level (https://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html).

Contextual colors - are those planned to be extensible by the client?

Cannot infer from the proposal if the set of Contextual colors may be extended by client, in order to address needs that might be specific to client's domain (like calling-alert, etc). Actually, if we are looking towards extensible theming mechanism, I would see this question being addressed (or would expect to see a plan of how we are going to address it).

What is proposed workflow for the client to generate color palette?

It is not absolutely clear from RFC what is the workflow client need to follow to create theme's palette. For example, the approach is clear for Bootstrap and Material:

@layershifter, the last point (related to user's workflow) to my mind is a crucial one, especially if we would state that color palette is a mandatory attribute of any theme. Could you, please, suggest what is our vision here?

layershifter commented 5 years ago

Material UI approach is not included in stats

I agree, it's strange that I missed it. However, if you will check #451, the result is quite similar to Material UI 😄 https://material.io/design/color/the-color-system.html#tools-for-picking-colors

'On' colors (for text, icons, other content..) What are the actions planned to address that?

Accessibility is a very important thing, but it is not covered by this RFC. We cannot cover all aspects in single run.

We discussed in offline that one of next steps will be implementation of color pairing tool that will allow to combine colors from palette and will cover accessibility aspects. We don't have an issue for that, yet.

Something like this browser's tool: image

https://design.firefox.com/photon/visuals/color.html#accessibility

Contextual colors - are those planned to be extensible by the client?

The AdditionalColors type covers this. These colors aren't included to siteVariables.colors (i.e. ColorPallette), but can be accessed as siteVariables.additionalColors.

What is proposed workflow for the client to generate color palette?

PR contains two palettes: https://github.com/stardust-ui/react/pull/451/files#diff-c29ebf6447647ff3c88ba3381b1afbcb https://github.com/stardust-ui/react/pull/451/files#diff-a5676258cb98e8e7e5310b952649c6dc

You can reference them as example. For now, I don't have more there. For next iteration our themes should use our color palette.

These aspects should covered as part of theming guide I think.

P.S. I renamed createPalette to createColorVariants because the name was confusing.