Skip to content

Conversation

@miroslavstastny
Copy link
Member

@miroslavstastny miroslavstastny commented Apr 24, 2023

All color palette tokens in the theme are named after colors. This RFC discusses options how we could name some of them using semantic names (danger, success...).

Related issues: #26168, #25720.

PREVIEW

@miroslavstastny miroslavstastny requested a review from a team as a code owner April 24, 2023 23:08
@github-actions github-actions bot added this to the April Project Cycle Q2 2023 milestone Apr 24, 2023
@github-actions github-actions bot added the Type: RFC Request for Feedback label Apr 24, 2023
@miroslavstastny miroslavstastny force-pushed the rfc/semantic-shared-colors branch from cf546ce to 9666d9e Compare April 24, 2023 23:14
@miroslavstastny miroslavstastny requested review from a team April 24, 2023 23:17
@fabricteam
Copy link
Collaborator

fabricteam commented Apr 24, 2023

📊 Bundle size report

🤖 This report was generated against 8ec648d4060906a32bad46a16e0eae13a7aa5959

@codesandbox-ci
Copy link

codesandbox-ci bot commented Apr 24, 2023

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 27b7d35:

Sandbox Source
@fluentui/react 8 starter Configuration
@fluentui/react-components 9 starter Configuration

@size-auditor
Copy link

size-auditor bot commented Apr 24, 2023

Asset size changes

Size Auditor did not detect a change in bundle size for any component!

Baseline commit: 8ec648d4060906a32bad46a16e0eae13a7aa5959 (build)

@miroslavstastny miroslavstastny changed the title rfc: Semantic shared colors RFC: Semantic shared colors Apr 24, 2023
@marcosmoura marcosmoura self-requested a review April 25, 2023 12:11
Comment on lines 131 to 145
### 4. Add semantic color tokens mapped to the current shared colors

All tokens are mapped to CSS variables with the same name: `colorPaletteRedBackground1` token is mapped to `--colorPaletteRedBackground1` CSS variable. From the very first release of FUIR9, we [always warned partners](https://react.fluentui.dev/?path=/docs/concepts-developer-theming--page#do-not-use-css-variables-directly) that they should never depend on this fact:

> Do not use CSS variables directly
>
> ⚠ Never use theme CSS variables directly! The CSS variables implementation of the theme is internal to the library. We might eventually decide to change the variable names, hash them or even use direct values instead of some variables. Always use the tokens to access the theme.

Add "status" slots to `cranberry`, add `orange` as a status color.

Add semantic color tokens which are mapped to the current shared colors. For example, `colorPaletteDangerBackground1` is mapped to `--colorPaletteRedBackground1`. `Danger` is still mapped to the old `red` color, but the token name is now semantic. Still not changed to `cranberry`.

Update the sources in the library to use the new colors.

Update the mapping from old colors to the new colors.
Copy link
Contributor

@behowell behowell Apr 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summarizing a suggestion made offline:
How about instead using the new token names ("danger", etc.) as css variables, and mapping the old (deprecated) token names ("red", etc.) to the new css variables:

/** @deprecated Use colorPaletteDangerBackground2 or colorPersonaRedBackground2 */
tokens.colorPaletteRedBackground2 = 'var(--colorPaletteDangerBackground2)'

This should mitigate/solve the first two cons of option 4:

  • 👍 It's possible to override danger separately from persona-red.
  • 👍 The css variable names map to the new, recommended token names for easier debugging.

One additional con of this:

  • 👎 If anyone is using the css variable names directly, they will break when we rename them to the new names.

Copy link
Contributor

@ling1726 ling1726 Apr 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 The css variable names map to the new, recommended token names for easier debugging.

This makes sense, we should optimize debugging for the recommended use case.

My question would be if there would be a future for colorPaletteRed as a token. If the intention is for users to stop using it and only use colorPaletteDanger (i.e. remove this token on next major), then @behowell's suggestion makes sense and I would vote for that.

If we still expect both tokens to be used past the next major, I don't think any kind of mappings in the FUI theme will be scalable because it overriding one token can affect other tokens. This would apply to any mapped tokens we intend to introduce.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm in favour of both @behowell idea and 1B: "deprecate" the tokens and create a V2 theme which does not contain them - let applications switch when they are ready.

that v2 gradual approach is something we will be adopting in "near-ish future" so would nicely align. also it would mitigate "unexpected" breaking changes.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added as option 4B.

It makes sense for colors which we are 'deprecating' - green and yellow should not be used anywhere so we introduce success and for backwards compatibility we map green to the new success.

👍 It's possible to override danger separately from persona-red.

Huh, actually I had ignored the fact that in option 4 we would have a different shape of theme and tokens. Added to Open Issues, will look into it next week.

that v2 gradual approach is something we will be adopting in "near-ish future" so would nicely align.

Realized the same problem here - introducing v2 theme would also require introducing v2 tokens which would require an import change in all .styles.ts files in the partner codebase :/ What would be our solution? Codemod?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My question would be if there would be a future for colorPaletteRed as a token. If the intention is for users to stop using it and only use colorPaletteDanger (i.e. remove this token on next major), then @behowell's suggestion makes sense and I would vote for that.

This is why I would rather prefer 4 to 4B out of these two options - red is still valid.
And I can understand danger being mapped to red (because the color is red). But I do not understand red being mapped to danger (but I might be biased).

Also designs change - as we see, danger mapping is changing from red to cranberry - semantic colors are less stable. But whatever is red will always be red - I would expect less changes here.

@behowell
Copy link
Contributor

I'll review this on behalf of @microsoft/cxe-red.

| `lightGreen` | available | available | No change |
| `marigold` | away | away | No change |

_‼️ TODO: verify with design_
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NOTE: after discussing the topic with @daisygeng, the current Design requirement is to introduce semantic color names only for danger, success and warning. I will be updating the RFC accordingly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the spec accordingly - if we ignore presence tokens, introducing just status tokens now shows different numbers (of tokens eventually added/affected).

@tudorpopams tudorpopams requested review from ValentinaKozlova and removed request for marcosmoura April 27, 2023 12:13
@tudorpopams
Copy link
Contributor

@ValentinaKozlova will review this on behalf of @microsoft/cxe-prg

- 👎 We will remove some "basic" colors `green`, `yellow` - are we sure those have been used as semantic colors only?
approach
- 👎 1A: adds ~30 new tokens
- 👎 If design decides to do the same for **presence** tokens, we will need to add another ~40 tokens to follow the same
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And I'm sure there will be new families of tokens requested for scenarios we don't forsee today.

| `darkOrange` | severe | **severe** should not be used anywhere. Keep `darkOrange` (temporarily) for Teams compatibility. |
| `yellow` | warning | Replace by semantic `warning`, mapping changed from `yellow` to `orange` |
| `berry` | OOF | No change |
| `lightGreen` | available | No change |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't look consistent that some tokens are named after colors e.g. lightGreen and some are after statuses, e.g. success. Maybe in future all tokens will use semantic names but what if these tokens will be needed not only for statuses

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree here. Let's take the current usages of red as an example (and for now ignore the fact that we are changing the danger from red to cranberry).

red is used for:

  1. danger
  2. busy
  3. persona

Now we will introduce danger status semantic color. But we cannot deprecate the red because that is still used for busy and persona.

Eventually we might decide to introduce presence semantic colors and add busy. After that we still need the red for persona so we cannot remove it, but can deprecate the slots used only for presence.

Also, this covers only the usages in the core library, but not partners' codebases. Design provides partners with guidelines but we cannot be 100% sure about what they really do.

@layershifter
Copy link
Member

I will review it on behalf of @microsoft/teams-prg


## Summary

All color palette tokens in the theme are named after colors. This RFC discusses options how we could name some of them using semantic names (`danger`, `success`...).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"All color palette tokens in the theme are named after colors."

Not sure that understand WDYM there.

| `colorPaletteRedBorder1` | status |
| `colorPaletteRedBorder2` | status |

This results in 150 (28 _ 3 + 7 _ 9 + 3) color tokens.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What means "_" there? Should it be "*"?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stubborn Prettier 🤷‍♂️

- 👎 There might be code which depends on the 1:1 token to CSS variable mapping (hello, [`themeToTokensObject`](https://github.com/microsoft/fluentui/blob/97c1c1ab218afb20e37bfc35936fd88177d439b4/packages/tokens/src/themeToTokensObject.ts#L14-L16)).
- 👍 4B: The css variable names map to the new, recommended token names for easier debugging.
- 👎 4B: If anyone is using the css variable names directly, they will break when we rename them to the new names.
- ‼️ In the current implementation we use `Theme` type for theme definition and `Record<keyof Theme, string>` for tokens in styles. In option 4 this would have to change - see [Open Issues](#open-issues).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I understand the Record<keyof Theme, string> issue here, but I also haven't spent much time looking at the theme code, so I might be misunderstanding the problem.

The way I was thinking of option 4B: the Theme object would contain entries for ALL of the old and new tokens, as if we had just gone and added a bunch of new tokens for the new color names, while keeping the old deprecated ones around. However, internally the deprecated tokens would map to the new CSS variable names to avoid significantly increasing our css variable count. But the fact that we're reusing the same CSS variable names wouldn't be exposed in the public API.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are two different objects - theme and tokens:

  1. theme is a "list of css variables" and their values which will be added to DOM.
  2. tokens are used in styles.ts files and map from Javascript object properties to css variable strings

Up until now, for every property which exists in tokens object, there is property in theme object and vice versa. This is enforced by the Theme typings.

In options 4, we are adding a new item to tokens, but map it to an existing item in theme.

Comment on lines +180 to +185
- K: `colorPalette` (`colorPaletteDangerBackground1`)
- L: `colorStatus` (`colorStatusDangerBackground1`)
- M: `colorSemantic` (`colorSemanticDangerBackground1`)
- n: anything else?

Also consider how the proposed name would work if we decide to introduce semantic **presence** tokens (`away`).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like colorStatus. If we add presence colors, we could use colorStatus for that as well, or colorPresence if we wanted to distinguish them.

- 👎 1A: can cause temporarily inconsistent UI colors between library and partners
- 👍 1B: we can use the current mapping in v1 theme and the new mapping in v2 theme - partners can control the moment when they switch to the new mapping
- 👎 1B: requires us maintaining the double amount of themes
- 👎 1C: breaks partners (the questions is how much, but...)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can geoff's query tool track down uses of those tokens?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked just TMP - there are 12 usages of green, 5 usages of yellow, but 121 usages of red.
So 1C would be difficult.

But even without breaking changes, we need to be careful with switching from red to cranberry regardless the name (danger or not) - some usages mean danger, other usages might mean persona or status - partners need to review all the usages and decide what the intent is and change accordingly.
To avoid inconsistent UI, best way forward would be to introduce danger and map it to red, let partners update their usages and only after that change danger from red to cranberry.


- 👍 Change does not affect components or partner code.
- 👍 No new tokens.
- 👎 Designers will scream as "Yellow and orange are two different colors!".
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

at least they would learn to stop naming color tokens by the color names?

- 👍 Semantic tokens without any unnecessary tokens.
- 👍 Controlled partner upgrade from old hex values to new values, but coupled with library upgrade.
- 👎 This is currently not supported by token pipeline - would require either changes there or custom implementation on library side.
- 👎 Semantic and status tokens are still coupled - the only way for the application to override `danger` is to override `red` (which will affect other parts of the UI).
Copy link
Member Author

@miroslavstastny miroslavstastny May 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This (the impossibility to override) might confuse partners, as they will want to override the danger, it will just not work.

@miroslavstastny
Copy link
Member Author

After considering all pros and cons and discussing the requirements with design again, I decided to add new status tokens for danger, success and warning, named colorStatus..., for example colorStatusDangerBackground1.
This approach adds 30 tokens, does not bring any new concept and allows existing and new tokens to be independently overriden.
See the implementation in #28006.

@miroslavstastny
Copy link
Member Author

This was implemented a year ago by just adding the required tokens. Closing the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Type: RFC Request for Feedback

Projects

None yet

Development

Successfully merging this pull request may close these issues.