Skip to content

Commit

Permalink
Improve the structure of global and semantic design tokens and explai…
Browse files Browse the repository at this point in the history
…n how they are related

Breaking changes:

- Renamed link color tokens from `--rui-color-action-link(-*)` to `--rui-color-text-link(-*)`.
- Removed internal design token `--rui-ratio-disabled-cursor` in favour of `--rui-cursor-not-allowed`.
  • Loading branch information
adamkudrna committed Mar 8, 2023
1 parent ff6205b commit 04b2042
Show file tree
Hide file tree
Showing 10 changed files with 253 additions and 228 deletions.
6 changes: 3 additions & 3 deletions doczrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -244,14 +244,14 @@ export default {
},
a: {
'&:active': {
color: 'var(--rui-color-action-link-active)',
color: 'var(--rui-color-text-link-active)',
textDecoration: 'var(--rui-text-decoration-link-active)',
},
'&:hover': {
color: 'var(--rui-color-action-link-hover)',
color: 'var(--rui-color-text-link-hover)',
textDecoration: 'var(--rui-text-decoration-link-hover)',
},
color: 'var(--rui-color-action-link)',
color: 'var(--rui-color-text-link)',
textDecoration: 'var(--rui-text-decoration-link)',
},
root: {
Expand Down
105 changes: 53 additions & 52 deletions src/docs/customize/theming/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,40 +8,34 @@ route: /customize/theming/overview
# Theming

From the very beginning, React UI has been designed with a great emphasis on
customizability. We decided to leverage CSS custom properties for this feature
customizability. We decided to leverage [CSS custom properties] for this feature
for two main reasons:

1. We take advantage of possibilities of **native CSS**. Preprocessors are still
a thing, but it's not necessary to go as far as for CSS-in-JS to make a UI
customizable.
1. We take advantage of the possibilities of **native CSS**. Preprocessors are
still a thing, but it's not necessary to go as far as for CSS-in-JS to make
a UI customizable, not even speaking of performance.

2. Thanks to JavaScript API, CSS custom properties are both **readable and
writable by JS**.

## Theming Options

[Design tokens](/foundation/design-tokens) are used to define common visual
properties like colors, fonts, borders, shadows, or spacing. CSS custom
properties are the technical representation of the design tokens in React UI.
[Design tokens](/foundation/design-tokens) define common visual properties like
colors, fonts, borders, shadows, or spacing. [CSS custom properties] are the
technical representation of the design tokens in React UI.

All CSS custom properties in React UI come prefixed with `rui-` so they don't
get in way of other custom properties in your project.

Just like the design tokens, the custom properties come grouped according to
their type:

1. alias design tokens,
2. component-specific tokens.
All CSS custom properties in React UI come prefixed with `rui` so they don't
get in the way of other custom properties in your project.

You can adjust any of the properties in your styles. See the [default theme] for
the full list of available custom properties.
the full list of available design tokens.

### Alias Design Tokens
### Global and Semantic Design Tokens

The alias token names are not complex nor long, so they are simply lowercase and
hyphenated.
Global and semantic token names are not complex or long. That is why they are
simply lowercase and hyphenated.

The alias token names are written in the following format:
The names are written in the following format:

`--rui-<type>-[<group>]-<name>-[<state>]`

Expand All @@ -50,15 +44,15 @@ Where:
- `<type>` is one of: `color`, `dimension`, `font-family`, `font-weight`,
`shadow`, as suggested by the [Design Tokens Format][dtf] proposal. However,
additional custom types like `font-size`, `line-height`, or `text-decoration`
are also used as they prove necessary.
have been added as they proved necessary.
- `<group>` optionally groups multiple related values, e.g. `text`,
`background`, `action`, etc.
- `<name>` is the name of the token, e.g. `primary`, `base`, or `light`. Scales
can be presented as numbered sequences, e.g. `space-[0-7]`, `size-[1-6]`, etc.
- `<state>` describes additional interaction variants of the token: `hover`,
`active`, `disabled`.
`focus`, `active`, or `disabled`.

Example alias design tokens represented by CSS custom properties:
Example global and semantic design tokens represented by CSS custom properties:

```css
:root {
Expand All @@ -68,25 +62,26 @@ Example alias design tokens represented by CSS custom properties:
}
```

️👉 Please note that **breakpoint values are exported as read-only** since CSS
custom properties [cannot be used within media queries][w3c-custom-properties]
(because a media query is not a CSS property).
️👉 Please note that **breakpoint values are read-only** (e.g. for JavaScript)
since CSS custom properties
[cannot be used within media queries][w3c-custom-properties] (because a media
query is not a CSS property).

### Component-Specific Tokens
### Component Tokens

It is also possible to adjust some properties on individual components level,
preferably by reusing (inheriting) the alias design tokens.
preferably by reusing (inheriting) the semantic design tokens.

Due to higher complexity, component-specific tokens use a naming convention that
many web developers will find familiar because it works like [BEM] (with
prefixes and component name syntax taken from [SUIT CSS], to be precise):
Due to higher complexity, component tokens use a naming convention that many web
developers will find familiar because it works like [BEM] (with prefixes and
component name syntax taken from [SUIT CSS], to be precise):

`--rui-<ComponentName>--[<modification(s)>]__[<element>]--[<modification(s)>]__<property>--[<modification>]`

Where:

- `<ComponentName>` stands for actual component name (e.g. `Button`,
`FormField` etc.) with a reasonable exception to form fields whose settings
- `<ComponentName>` stands for the actual component name (e.g. `Button`,
`FormField`, etc.) with a reasonable exception to form fields whose settings
are widely shared and therefore grouped as `FormField` options.
- `<modifications(s)>` can be one or more modifiers, typically a variant (e.g.
`primary`, `filled`, `box`) or interaction state (`default`, `hover`,
Expand All @@ -97,7 +92,7 @@ Where:
where a CSS property wouldn't tell enough (e.g. `initial-offset`,
`check-background-color`, `tap-target-size`).

Example component-specific custom properties:
Example component tokens:

```css
:root {
Expand All @@ -112,41 +107,47 @@ Example component-specific custom properties:
}
```

### CSS, or SCSS?
## Best Practices

1. It's a good idea to start with changing the **global tokens first**. Adjust
any context-agnostic values to see how the system reacts and scales.

2. Widely reused context-aware settings such as semantic colors, typography, or
borders define the character of your design system which is stored in the
**semantic tokens** layer.

3. Having finished the customization at the global and semantic level, you can
**then proceed to customize the appearance of individual components** — if
necessary at all.

Even then you should also reuse existing semantic design tokens as much as
possible to ensure that your UI is consistent and works as a system.

For the same reason, if you have any custom components in your UI, you should
**reuse the semantic design tokens in your own CSS** too.

## CSS, or Sass?

Colors, breakpoints, and SVG definitions used in `theme.scss` are preprocessed
with SCSS first. This enables us to:
with Sass first. This enables us to:

- generate our internal color palette programmatically,
- keep actual breakpoint values in a single place in the code,
- keep `theme.scss` uncluttered by inline SVG.

It's entirely up to you what format you decide to use for storing the theme.
Both `theme.scss` and `theme.css` will work equally well. It only matters if the
custom properties make it from the theme file to browser.
custom properties make it from the theme file to the browser.

👉 Just remember everything in the [theme constants] directory is intended only
for usage within `theme.scss`. Otherwise, the theming system may not work as
expected. We recommend calling custom properties from `theme.scss` either
directly in your stylesheet, or through an intermediate, shareable layer like
`MyComponent/_theme.scss` or
`styles/shared-by-components/_my-sass-variables-referring-to-theme.scss`
(latter of which is the approach we use).

## Best Practices

It's a good idea to start with changing the **alias design tokens first**.
Widely reused settings such as colors, typography, borders, or spacing values
should be adjusted first because they define basic appearance of all components.

Having finished the customization at the global level, you can **then proceed to
customizing the appearance of individual components** — if necessary at all.
Even then you should also reuse existing alias design tokens as much as
possible to ensure that your UI is consistent and works as a system.

For the same reason, if you have any custom components in your UI, you should
**reuse the alias design tokens in your own CSS** too.
(the latter of which is the approach we use).

[CSS custom properties]: https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties
[default theme]: https://github.com/react-ui-org/react-ui/blob/master/src/lib/theme.scss
[dtf]: https://design-tokens.github.io/community-group/format/
[theme constants]: https://github.com/react-ui-org/react-ui/blob/master/src/lib/styles/theme-constants
Expand Down
11 changes: 5 additions & 6 deletions src/docs/foundation/accessibility.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,11 @@ The active area of interactive elements should be properly sized so that the
elements can be easily targeted on touch screens. Recommended dimensions may
vary from platform to platform, however a commonly used size is 7–10 mm.

Default tap target size in React UI is set to **10 mm** and is used by all
potentially small interactive components like [Alert](/components/alert)
close button, [CheckboxField](/components/checkbox-field), or
[Toggle](/components/toggle). Tap target size can be adjusted via the
`--rui-dimension-tap-target-size` custom property (see
[Theming](/customize/theming/overview) to learn how).
Default tap target size in React UI is used by all potentially small interactive
components like [Alert](/components/alert) close button,
[CheckboxField](/components/checkbox-field), or [Toggle](/components/toggle).
Tap target size can be adjusted via the `--rui-dimension-tap-target-size`
custom property (see [Theming](/customize/theming/overview) to learn how).

📖 [Read more about touch targets at Norman Nielsen Group.][nn-group]

Expand Down
75 changes: 40 additions & 35 deletions src/docs/foundation/colors.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,47 +10,58 @@ import Swatch from '../_components/Swatch'

Colors help you communicate the structure of your UI, emphasize any important
information, or signal different states of the UI. **Use colors intentionally**
— they are not a decoration, they should always serve a purpose.
— they are not decoration and should always serve a purpose.

👉 All colors on this page can be changed by
[overriding](/customize/theming/overview) values in your
[design tokens](/foundation/design-tokens).

## General Guidelines

- **All colors in React UI are strictly semantic: they always target a specific
use case. You are encouraged to apply any color palettes you want and map them
onto the semantic colors of React UI.**
- In general, all colors in React UI are for either **static** (text colors and
most of the background colors) or **interactive** use cases (action colors,
feedback colors). However, some colors are designed to be either of them:
neutral colors can be used for both static and interactive parts, similarly to
primary border color.
- **Most colors in React UI are semantic: they bear a meaning and target a
specific use case.** The only non-semantic exception is the
[neutral colors](#neutral-colors) that are included in React UI due to their
frequent usage in UI designs.
- **React UI does not try to suggest any global color palettes.** Instead, you
are encouraged to pick any color palettes you want and map them onto the
semantic colors of React UI.
- In general, colors in React UI can be used for either **static**
(most of the [text colors](#text-colors) and most of the
[background colors](#background-colors)) or **interactive** use cases
([action colors](#action-colors), [feedback colors](#feedback-colors)).
However, some colors are designed to be either:
[neutral colors](#neutral-colors) can be used for static and interactive parts
similarly to the primary [border color](#border-colors).
- Interactive color variants always define **hover** and **active** (pressed)
states.
- Many colors suggest **what color should be used for text** placed on them. You
don't have to think if black or white is better — just use `on-primary` for
text on primary color background or `on-success` for success color background,
and you should be safe.
- Action, feedback, and neutral colors suggest **what color should be used** for
the text placed on them. You don't have to think if black or white makes a
better contrast — just use `on-primary` for text on primary color background
or `on-success` for success color background, and you should be safe.

## Text Colors

Colors reserved for text. The text can have primary or secondary priority. Both
priorities can be suppressed with the `disabled` variants.
Colors reserved for text. Base text can have primary or secondary priority,
while both priorities can be suppressed with the `disabled` variants. Last but
not least, the text colors define the color of links.

<div>
<Swatch color="text-primary" />
<Swatch color="text-primary-disabled" />
<Swatch color="text-secondary" />
<Swatch color="text-secondary-disabled" />
</div>
<div>
<Swatch color="text-link" />
<Swatch color="text-link-hover" />
<Swatch color="text-link-active" />
</div>

## Action Colors

Action colors communicate the **importance** of an action which can be primary
or secondary. Using the `selected` color, you can also mark an action as the one
currently selected. Last but not least, the action colors define the color of
links, too.
or secondary. Using the _selected_ color, you can also mark an action as the
currently selected.

<div>
<Swatch color="action-primary" />
Expand All @@ -70,17 +81,12 @@ links, too.
<Swatch color="action-selected-active" />
<Swatch color="action-on-selected" />
</div>
<div>
<Swatch color="action-link" />
<Swatch color="action-link-hover" />
<Swatch color="action-link-active" />
</div>

## Feedback Colors

Feedback colors help communicate a **meaning**: green means success, orange
means warning, and red means danger or error. On top of that, there are a few
more feedback colors to fit various situations.
Feedback colors help communicate a meaning: green means success, orange means
warning, and red means danger or error. On top of that, there are a few more
feedback colors to fit various design situations.

<div>
<Swatch color="feedback-success" />
Expand Down Expand Up @@ -144,7 +150,7 @@ Colors reserved for backgrounds.

### Content Layers

Backgrounds for the fundamental UI areas and layered content.
Backgrounds for the fundamental UI areas and content layering.

👉 Content layers can be separated from background using their
[shadow counterparts](/foundation/shadows): `background-layer-1` +
Expand Down Expand Up @@ -173,8 +179,8 @@ the _basic_ background is the default go-to background for components.

Backgrounds to highlight interactive areas on hover and during interaction.

💡 Please note the default interactive background is always transparent so it
does not get in the way of the underlying component background.
💡 Please note the default interactive background is always transparent, so it
does not stand in the way of the underlying component background.

<div>
<Swatch color="background-interactive" />
Expand Down Expand Up @@ -229,23 +235,22 @@ primary border.

## Applying Colors

Components can apply colors above using one or more of the following color
palettes.
Components can apply colors above using one or more following color groups.

### Component Colors

Some components ([Alert](/components/alert), [Badge](/components/badge),
[Button](/components/button), and more) come in more color variants to help you
better reflect their importance or nature of their content. Following colors
are available in such cases:
better reflect their place in content hierarchy or the meaning of their content.
Following colors are available in such cases:

- **action colors (actionable components only):** `primary`, `secondary`, and
`selected`,
- **feedback colors:** `success`, `warning`, `danger`, `help`, `info`, and
`note`,
- **neutral colors:** `light` and `dark`.

There is always a reasonable default for the component in question which can be
There is always a reasonable default for the component in question that can be
changed to any of supported values above through the `color` prop.

### Validation States
Expand All @@ -259,5 +264,5 @@ apply selected [feedback colors](#feedback-colors) for individual states:
- `warning` feedback color for **warning** state,
- `danger` feedback color for **invalid** state.

Validation state is always optional so default styling is applied for the
Validation state is always optional. Default styling is applied for the given
component when its `validationState` prop is not specified.
Loading

0 comments on commit 04b2042

Please sign in to comment.