-
Notifications
You must be signed in to change notification settings - Fork 32
[Feature]: Research and concept color tokens #594
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
Comments
Ok, doing this research and experimenting with the structure, we are able to define the following spec of color tokens:
1. SchemaEach color token follows schema of
Currently defined types:
Currently defined variants:
2. Variant hierarchyThe hierarchy follows the orders:
3. Recap / Questions
|
After yesterday's discussion, we concluded that more complex components like Selects should allow the changing of color properties (backgroundColor, color, and borderColor), but only when necessary. For example, in the snippet below, developers should only be able to change the const Select = ({ color }) => {
return (
<select>
<label color={color}>Select item</label>
<option>Flowers</option>
<option>Furniture</option>
</select>
);
};
<Select color="muted" />; To achieve this, we need to establish boundaries for the more complex components (Input, Combobox, Select, and Multiselect) in MacawUI, allowing developers to change colors only in specified parts of those components. |
Meeting notes:
Possible issues:
|
Really like the changes, specially making more strict which colors are accepted in what Component 🚀 Feedback from me: I would rethink our color naming. In forms, we usually have a label and a description field beneath the input. Let's say the form has bg |
3 cents on components colors. I think we should have following values layers:
I think we should style components with variables, not props. By default Macaw will style them with proper usage and for majority of users knowing tokens will be not necessary, because there will be semantic aliases for everything. So my 3 cents is to ensure components will have aliases. So when we change button's border, we only change its local mapping, not entire theme |
Ok, to recap all of feedback and research. Definition of tokensSeems like we can simplify the tokens and instead doing sophisticated naming and rules, we can just do the mapping. I would see three levels of tokens: raw token, semantic level and component one: We have the following tokens: /* raw colors */
--red: red
--blue: blue
--green: green
/* semantic colors */
--background-default: var(--red)
--background-muted: var(--green)
/* component level mapping */
--bg-button: var(--background-default) Now button implementation and usage: const Button = (props) => <Box backgroundColor="bg-button" {...props} />
<Button>Click me!</Button> // by default it's red
<Button backgroundColor="background-muted">Click me!</Button> // I change color, but still based on semantic colors
<Button __backgroundColor="#3cb371">Click me!</Button> // in the very specific place i want it to be shade of green By doing this, the developer is able to:
Raw tokens naming and structureRaw colors can take structure of: where:
Examples: Semantic tokens naming and structureLayer that represents abstraction for colors for variety of elements on the UI eg. borders or backgrounds.
where:
Example: --s-color-background-default: var(--gray-100);
--s-color-background-muted: var(--gray-50);
--s-color-background-strong: var(--gray-400);
--s-color-border-default: var(--red-200); Component tokens naming and structureConsidering states, variants and use cases, based on our discussions, the following schema naming would be suitable:
Example: --c-button-primary-background: var(--color-background-default);
--c-button-primary-border: var(--color-border-default);
--c-button-primary-background-hover: var(--color-background-muted);
--c-button-primary-background-focus: var(--color-background-strong); |
Answering some:
Such things can be autogenerated from theme. Actually each value is a "private field" for a component, so the only reason to expose it is to adjust theme. E.g. "change background of Modal, without changing all backgrounds". So only need to document is to expose available tokens
The middle step is to avoid globals. e.g.
Then, there is a Modal
Then, I want to change modals to be slightly darker
Instead:
Why would they?
Tokens for components will be private for components. Tokens for "card" will not compile under "calendar" (at least how we discussed it with @andrzejewsky )
I don't get it, this is part of using CSS variables?
The developer should introduce new color because he add new component |
It doesn't change the fact that you endup mapping hundreds of tokens
To change the modals you change modals mapping
To change the theme you change I don't see how these examples justify the need for singleton tokens, or which problem it solves. Your examples are only relevant if the token is used twice which is not the case.
That is not purpose of a design system, and neither we can accept every component that app makers need
Exactly, that is why having native components using something else makes it harder to reference and learn the system
Developers should use colors from the theme, you can't introduce new color without breaking out from the theme |
After some discussion with @lkostrowski it turns out one of the motivations to have singletons is to override the theme. However if any theme can change the rules of mappings we loose any predictability and will create a risk of apps looking different. Example: |
After conducting further research, we have decided to adopt the following approach for naming tokens. We will have two types of tokens for colors: design system tokens and tokens for semantic components. Design system tokensDesign system tokens will have following structure:
Where:
LayersLayer number 1 is used as default application color e.g dashboard background. Layer number 2 is used for e.g dashboard sidebar color. User can use layers on top of the each other in one direction: 1 -> 2 -> 3. Disabled is special layer for disabled elements StateDifferent variations for hover or focused states Semantic components tokensSemantic components tokens will have following structure:
Where:
Note Inputs for now will have transparent background. Text and border will be using layer 1. StateDifferent variations for hover or focused states Tokens table
|
Looking good in general, I like I don't like this:
We use the same symbol Also, we mix specificity, the first one is generic ("button"), the second is more specific (text is part of button). So maybe we should actually have
Optionally we can also add another symbol for component name join, eg
or
|
Thanks for the comment - I'm wondering if we should have sematic tokens in this form:
as it will be working nicely with how we group our color tokens inside contract (we sort them into three groups: 'background', 'text' and 'border') |
In macaw UI we have theme system, that provides design tokens. Each token represents some value: eg color value, font size value, font weight value end etc. Focussing on the colors, we are also distinguishing them depending its context. Given twe have colors for borders, bachgrounds, foregrounds and so on.
Since it works fine in general, but creates a problem, problem of choice. The end user, doesn't know which color use to be contrasted with the other. As example: which color of font or background to use to be contrasted on another background.
We need to reveal what we want to approach this problem. As example we can consider color hierarchy where each part of token name represent the layer in tree:
Schema:
--[type]-[element]-[role]-[variant]-[state]
In this context, going from down to up colors are always contrasted, when used accordingly to hierarchy.
AC:
The text was updated successfully, but these errors were encountered: