Skip to content

feat(alert,visual): theming with CSS variables (#DS-2679) #208

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

Merged
merged 16 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions docs/guides/theming-2.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
### Что нового?

Теперь использование компонентов стало проще! Мы движемся к полной изоляции компонентов, что позволит вам легко подключать и использовать их. Кроме того, мы убрали необходимость пробрасывать токены для задания цветов компонентам.

### Как использовать?

1. Импортируйте компонент
2. Добавьте `kbq-theme-light` селектор к элементу `<body>` вашего HTML-документа для использования светлой темы и `kbq-theme-dark` для темной темы.

Для переключения тем используйте [ThemeService.](/packages/components/core/services/theme.service.ts)

### Доступные селекторы для темной и светлой темы

Вот таблица доступных селекторов для темной и светлой тем:

| Тема | Селекторы |
| ------- | ------------------------------------------ |
| Темная | .kbq-dark, .theme-dark, .kbq-theme-dark |
| Светлая | .kbq-light, .theme-light, .kbq-theme-light |

Мы рекомендуем использовать те селекторы, которые указаны в сервисе `ThemeService` (`kbq-theme-dark` для темной и `kbq-theme-light` для светлой).

### Как задать кастомные значения компоненту дизайн-системы?

Изменить цвета, размеры и шрифты можно задав соответствующие значения CSS-переменным компонента.
Например:

```css
.kbq-theme-dark {
--kbq-alert-default-contrast-container-background: custom-color;
--kbq-alert-default-contrast-container-title: custom-color;
}
```

### Совместимость

Работает стабильно с `@koobiq/design-tokens@3.4.0`.

### Как применить уже имеющиеся кастомные дизайн-токены?

Темы, где значения дизайн-токенов были перезаписаны с помощью Style-Dictionary,
применяются аналогично [заданию кастомных значений компонентам.](#как-задать-кастомные-значения-компоненту-дизайн-системы)

### Нужно ли что-то делать, если уже используются CSS-переменные из пакета @koobiq/design-tokens?

Да, необходимо удалить CSS-переменные для компонентов, которые уже используют стандартные значения из коробки.

В каких файлы необходимо внести изменения:

- css-tokens.css - размеры компонента
- css-tokens-light.css - цвета компонента для светлой темы
- css-tokens-dark.css - цвета компонента для темной темы
- css-tokens-font.css - шрифт, его размеры и параметры для компонента

Для каких компонентов удалить CSS-переменные (в них используются значения по умолчанию):

- [alert](/packages/components/alert/alert-tokens.scss)

### Откуда теперь брать значения дизайн-токенов для компонентов?

Все актуальные значения для компонентов хранятся в репозитории [@koobiq/design-tokens](https://github.com/koobiq/design-tokens).
Сгенерированные на основе дизайн-токенов CSS-переменные компонентов позволяют сделать их использование более удобным, а также ускорить их разработку, в том числе проведение дизайн-ревью.

### Что планируется сделать дальше?

Мы планируем применить эти улучшения ко всем компонентам и использовать семантические значения для CSS-переменных компонентов, такие как `var(--kbq-size-m)` вместо `12px`.
Это сделает код более читаемым и поддерживаемым.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@
"build:docs-examples": "ng build docs-examples",
"build:cli": "rimraf dist/cli && rollup -c ./packages/cli/rollup.config.js && node ./packages/cli/scripts/copy-meta-to-dist.js",
"build:tokens:docs": "node ./apps/docs/scripts/build-tokens.js",
"build:tokens:components": "node ./tools/tokens/build-each-component.js",
"build:docs-content": "ts-node --project ./tools/markdown-to-html/tsconfig.json ./tools/markdown-to-html/transform-markdown.ts && yarn run docs:api-gen",
"build:package-docs-content": "ts-node --project ./tools/package-docs-content/tsconfig.json ./tools/package-docs-content/package-docs-content.ts",
"styles:built-all": "ts-node --project tools/scss-compiler/tsconfig.json tools/scss-compiler/scss-bundle.ts",
Expand Down
2 changes: 1 addition & 1 deletion packages/components-dev/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

<title>Dev Example</title>
</head>
<body class="kbq-app-background">
<body class="kbq-app-background kbq-theme-light">
<app />
</body>
</html>
36 changes: 16 additions & 20 deletions packages/components/alert/_alert-theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,73 +4,69 @@
@use '../core/styles/typography/typography-utils' as *;
@use '../core/styles/common/tokens' as *;

@mixin kbq-alert-style($component, $type, $style-name) {
$style: map.get($component, $type, $style-name);

background: kbq-css-variable(alert-#{$type}-#{$style-name}-container-background, map.get($style, background));
@mixin kbq-alert-style($type, $style-name) {
background: kbq-css-variable(alert-#{$type}-#{$style-name}-container-background);

.kbq-alert__title {
color: kbq-css-variable(alert-#{$type}-#{$style-name}-container-title, map.get($style, title));
color: kbq-css-variable(alert-#{$type}-#{$style-name}-container-title);
}

.kbq-alert__text {
color: kbq-css-variable(alert-#{$type}-#{$style-name}-container-text, map.get($style, text));
color: kbq-css-variable(alert-#{$type}-#{$style-name}-container-text);
}
}

@mixin kbq-alert-theme($theme) {
$alert: map.get(map.get($theme, components), alert);

@mixin kbq-alert-theme() {
.kbq-alert__close:focus {
outline: none;
}

.kbq-alert.kbq-alert_default {
&.kbq-alert_contrast {
@include kbq-alert-style($alert, default, contrast);
@include kbq-alert-style(default, contrast);
}

&.kbq-alert_error {
@include kbq-alert-style($alert, default, error);
@include kbq-alert-style(default, error);
}

&.kbq-alert_warning {
@include kbq-alert-style($alert, default, warning);
@include kbq-alert-style(default, warning);
}

&.kbq-alert_success {
@include kbq-alert-style($alert, default, success);
@include kbq-alert-style(default, success);
}

&.kbq-alert_theme {
@include kbq-alert-style($alert, default, theme);
@include kbq-alert-style(default, theme);
}
}

.kbq-alert.kbq-alert_colored {
&.kbq-alert_contrast {
@include kbq-alert-style($alert, colored, contrast);
@include kbq-alert-style(colored, contrast);
}

&.kbq-alert_error {
@include kbq-alert-style($alert, colored, error);
@include kbq-alert-style(colored, error);
}

&.kbq-alert_warning {
@include kbq-alert-style($alert, colored, warning);
@include kbq-alert-style(colored, warning);
}

&.kbq-alert_success {
@include kbq-alert-style($alert, colored, success);
@include kbq-alert-style(colored, success);
}

&.kbq-alert_theme {
@include kbq-alert-style($alert, colored, theme);
@include kbq-alert-style(colored, theme);
}
}
}

@mixin kbq-alert-typography($config) {
@mixin kbq-alert-typography() {
.kbq-alert {
@include kbq-typography-css-variables(alert, text);

Expand Down
132 changes: 132 additions & 0 deletions packages/components/alert/alert-tokens.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
.kbq-alert {
--kbq-alert-size-normal-container-border-radius: 12px;
--kbq-alert-size-normal-container-padding-top: 0;
--kbq-alert-size-normal-container-padding-right: 8px;
--kbq-alert-size-normal-container-padding-bottom: 0;
--kbq-alert-size-normal-container-padding-left: 8px;
--kbq-alert-size-normal-content-padding-top: 16px;
--kbq-alert-size-normal-content-padding-right: 8px;
--kbq-alert-size-normal-content-padding-bottom: 16px;
--kbq-alert-size-normal-content-padding-left: 12px;
--kbq-alert-size-normal-icon-margin-top: 16px;
--kbq-alert-size-normal-icon-margin-right: 0;
--kbq-alert-size-normal-icon-margin-bottom: 16px;
--kbq-alert-size-normal-icon-margin-left: 12px;
--kbq-alert-size-normal-icon-padding-top: 4px;
--kbq-alert-size-normal-title-margin-bottom: 4px;
--kbq-alert-size-normal-close-button-margin-top: 8px;
--kbq-alert-size-normal-close-button-margin-left: 2px;
--kbq-alert-size-normal-button-stack-padding-top: 8px;
--kbq-alert-size-normal-button-stack-padding-bottom: 2px;
--kbq-alert-size-normal-no-title-icon-margin-top: 16px;
--kbq-alert-size-normal-no-title-icon-padding-top: 2px;
--kbq-alert-size-compact-container-border-radius: 12px;
--kbq-alert-size-compact-container-padding-top: 0;
--kbq-alert-size-compact-container-padding-right: 8px;
--kbq-alert-size-compact-container-padding-bottom: 0;
--kbq-alert-size-compact-container-padding-left: 16px;
--kbq-alert-size-compact-content-padding-top: 12px;
--kbq-alert-size-compact-content-padding-right: 8px;
--kbq-alert-size-compact-content-padding-bottom: 12px;
--kbq-alert-size-compact-content-padding-left: 0;
--kbq-alert-size-compact-icon-margin-top: 12px;
--kbq-alert-size-compact-icon-margin-right: 8px;
--kbq-alert-size-compact-icon-padding-top: 4px;
--kbq-alert-size-compact-title-margin-bottom: 2px;
--kbq-alert-size-compact-close-button-margin-top: 8px;
--kbq-alert-size-compact-close-button-margin-left: 2px;
--kbq-alert-size-compact-button-stack-padding-top: 8px;
--kbq-alert-size-compact-button-stack-padding-bottom: 2px;
--kbq-alert-size-compact-no-title-icon-margin-top: 12px;
--kbq-alert-size-compact-no-title-icon-padding-top: 2px;
--kbq-alert-font-title-font-size: 18px;
--kbq-alert-font-title-line-height: 26px;
--kbq-alert-font-title-letter-spacing: normal;
--kbq-alert-font-title-font-weight: 600;
--kbq-alert-font-title-font-family: 'TT-Positive', Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI',
'Helvetica Neue', Arial, sans-serif;
--kbq-alert-font-title-text-transform: null;
--kbq-alert-font-title-font-feature-settings: 'calt', 'kern', 'liga';
--kbq-alert-font-title-compact-font-size: 16px;
--kbq-alert-font-title-compact-line-height: 24px;
--kbq-alert-font-title-compact-letter-spacing: -0.011em;
--kbq-alert-font-title-compact-font-weight: 600;
--kbq-alert-font-title-compact-font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue',
Arial, sans-serif;
--kbq-alert-font-title-compact-text-transform: null;
--kbq-alert-font-title-compact-font-feature-settings: 'calt', 'kern', 'liga', 'ss01', 'ss04';
--kbq-alert-font-text-font-size: 14px;
--kbq-alert-font-text-line-height: 20px;
--kbq-alert-font-text-letter-spacing: -0.006em;
--kbq-alert-font-text-font-weight: normal;
--kbq-alert-font-text-font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue', Arial,
sans-serif;
--kbq-alert-font-text-text-transform: null;
--kbq-alert-font-text-font-feature-settings: 'calt', 'kern', 'liga', 'ss01', 'ss04';
}

:where(.kbq-light, .theme-light, .kbq-theme-light) {
--kbq-alert-default-contrast-container-background: hsla(229, 15%, 92%, 100%);
--kbq-alert-default-contrast-container-title: hsla(229, 15%, 15%, 100%);
--kbq-alert-default-contrast-container-text: hsla(229, 15%, 15%, 100%);
--kbq-alert-default-error-container-background: hsla(229, 15%, 92%, 100%);
--kbq-alert-default-error-container-title: hsla(229, 15%, 15%, 100%);
--kbq-alert-default-error-container-text: hsla(229, 15%, 15%, 100%);
--kbq-alert-default-warning-container-background: hsla(229, 15%, 92%, 100%);
--kbq-alert-default-warning-container-title: hsla(229, 15%, 15%, 100%);
--kbq-alert-default-warning-container-text: hsla(229, 15%, 15%, 100%);
--kbq-alert-default-success-container-background: hsla(229, 15%, 92%, 100%);
--kbq-alert-default-success-container-title: hsla(229, 15%, 15%, 100%);
--kbq-alert-default-success-container-text: hsla(229, 15%, 15%, 100%);
--kbq-alert-default-theme-container-background: hsla(229, 15%, 92%, 100%);
--kbq-alert-default-theme-container-title: hsla(229, 15%, 15%, 100%);
--kbq-alert-default-theme-container-text: hsla(229, 15%, 15%, 100%);
--kbq-alert-colored-contrast-container-background: hsla(229, 15%, 92%, 100%);
--kbq-alert-colored-contrast-container-title: hsla(229, 15%, 15%, 100%);
--kbq-alert-colored-contrast-container-text: hsla(229, 15%, 15%, 100%);
--kbq-alert-colored-error-container-background: hsla(7, 97%, 90%, 100%);
--kbq-alert-colored-error-container-title: hsla(229, 15%, 15%, 100%);
--kbq-alert-colored-error-container-text: hsla(229, 15%, 15%, 100%);
--kbq-alert-colored-warning-container-background: hsla(38, 100%, 85%, 100%);
--kbq-alert-colored-warning-container-title: hsla(229, 15%, 15%, 100%);
--kbq-alert-colored-warning-container-text: hsla(229, 15%, 15%, 100%);
--kbq-alert-colored-success-container-background: hsla(104, 64%, 80%, 100%);
--kbq-alert-colored-success-container-title: hsla(229, 15%, 15%, 100%);
--kbq-alert-colored-success-container-text: hsla(229, 15%, 15%, 100%);
--kbq-alert-colored-theme-container-background: hsla(216, 100%, 85%, 100%);
--kbq-alert-colored-theme-container-title: hsla(229, 15%, 15%, 100%);
--kbq-alert-colored-theme-container-text: hsla(229, 15%, 15%, 100%);
}

:where(.kbq-dark, .theme-dark, .kbq-theme-dark) {
--kbq-alert-default-contrast-container-background: hsla(229, 15%, 25%, 100%);
--kbq-alert-default-contrast-container-title: hsla(229, 15%, 80%, 100%);
--kbq-alert-default-contrast-container-text: hsla(229, 15%, 80%, 100%);
--kbq-alert-default-error-container-background: hsla(229, 15%, 25%, 100%);
--kbq-alert-default-error-container-title: hsla(229, 15%, 80%, 100%);
--kbq-alert-default-error-container-text: hsla(229, 15%, 80%, 100%);
--kbq-alert-default-warning-container-background: hsla(229, 15%, 25%, 100%);
--kbq-alert-default-warning-container-title: hsla(229, 15%, 80%, 100%);
--kbq-alert-default-warning-container-text: hsla(229, 15%, 80%, 100%);
--kbq-alert-default-success-container-background: hsla(229, 15%, 25%, 100%);
--kbq-alert-default-success-container-title: hsla(229, 15%, 80%, 100%);
--kbq-alert-default-success-container-text: hsla(229, 15%, 80%, 100%);
--kbq-alert-default-theme-container-background: hsla(229, 15%, 25%, 100%);
--kbq-alert-default-theme-container-title: hsla(229, 15%, 80%, 100%);
--kbq-alert-default-theme-container-text: hsla(229, 15%, 80%, 100%);
--kbq-alert-colored-contrast-container-background: hsla(229, 15%, 25%, 100%);
--kbq-alert-colored-contrast-container-title: hsla(229, 15%, 80%, 100%);
--kbq-alert-colored-contrast-container-text: hsla(229, 15%, 80%, 100%);
--kbq-alert-colored-error-container-background: hsla(7, 97%, 15%, 100%);
--kbq-alert-colored-error-container-title: hsla(229, 15%, 80%, 100%);
--kbq-alert-colored-error-container-text: hsla(229, 15%, 80%, 100%);
--kbq-alert-colored-warning-container-background: hsla(38, 100%, 14%, 100%);
--kbq-alert-colored-warning-container-title: hsla(229, 15%, 80%, 100%);
--kbq-alert-colored-warning-container-text: hsla(229, 15%, 80%, 100%);
--kbq-alert-colored-success-container-background: hsla(104, 64%, 12%, 100%);
--kbq-alert-colored-success-container-title: hsla(229, 15%, 80%, 100%);
--kbq-alert-colored-success-container-text: hsla(229, 15%, 80%, 100%);
--kbq-alert-colored-theme-container-background: hsla(216, 100%, 20%, 100%);
--kbq-alert-colored-theme-container-title: hsla(229, 15%, 80%, 100%);
--kbq-alert-colored-theme-container-text: hsla(229, 15%, 80%, 100%);
}
5 changes: 5 additions & 0 deletions packages/components/alert/alert.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

@use '../core/styles/common/tokens' as *;

@use './alert-theme' as *;

.kbq-alert {
display: flex;

Expand Down Expand Up @@ -119,3 +121,6 @@
margin-left: kbq-css-variable(alert-size-compact-close-button-margin-left);
}
}

@include kbq-alert-theme();
@include kbq-alert-typography();
2 changes: 1 addition & 1 deletion packages/components/alert/alert.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export class KbqAlertControl {}
@Component({
selector: 'kbq-alert',
templateUrl: './alert.component.html',
styleUrls: ['alert.component.scss'],
styleUrls: ['alert.component.scss', 'alert-tokens.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
host: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export class KbqCommonModule {
console.warn(
'Could not find koobiq core theme. Most koobiq ' +
'components may not work as expected. For more info refer ' +
'to the theming guide: link there'
'to the theming guide: https://koobiq.io/main/theming/overview'
);
}

Expand Down
3 changes: 0 additions & 3 deletions packages/components/core/styles/_koobiq-theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
@use 'theming/scrollbar-theme' as *;

@use '../selection/pseudo-checkbox/pseudo-checkbox-theme' as *;
@use '../../alert/alert-theme' as *;
@use '../../autocomplete/autocomplete-theme' as *;
@use '../../badge/badge-theme' as *;
@use '../../button/button-theme' as *;
Expand Down Expand Up @@ -59,7 +58,6 @@
@mixin koobiq-theme($theme) {
@include kbq-core-theme($theme);

@include kbq-alert-theme($theme);
@include kbq-autocomplete-theme($theme);
@include kbq-badge-theme($theme);
@include kbq-button-theme($theme);
Expand Down Expand Up @@ -122,7 +120,6 @@
@include kbq-base-typography();
@include kbq-markdown-base-typography();

@include kbq-alert-typography($config);
@include kbq-badge-typography($config);
@include kbq-button-typography($config);
@include kbq-button-toggle-typography($config);
Expand Down
1 change: 1 addition & 0 deletions tools/cspell-locales/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"инпуте",
"кастомизируемых",
"кастомное",
"кастомные",
"кликает",
"контрол",
"контролам",
Expand Down
Loading