Skip to content
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

feat: theme versions #3581

Draft
wants to merge 16 commits into
base: next
Choose a base branch
from
Draft

feat: theme versions #3581

wants to merge 16 commits into from

Conversation

zhzz
Copy link
Member

@zhzz zhzz commented Dec 28, 2024

Версионирование тем

Добавляем новую фичу для облегчения обновлений нашей библиотеки.

Проблема

В дизайн-системе время от времени возникает необходимость сделать "визуальные изменения" компонентов. Например, это могут быть новые цвета или что-то другое, немного меняющее внешний их вид и верстку (раз, два).

Такие изменения полезны, они поддерживают дизайн-систему в актуальном и рабочем состоянии. И, как правило, они не очень срочные, т.е. пользователям не обязательно их применять сразу же как только они появились. Но зачастую, чтобы их применить и адаптировать в проекте пользователя, ему нужно потратить дополнительные ресурсы: обновить скриншотные тесты, подправить внешний вид других элементов на странице и протестировать, что дизайн в целом остался консистентным. А мы стремимся сделать процесс обновления библиотеки максимально простым и бесплатным для пользователей.

С другой стороны, мы также стремимся и к тому, чтобы пользовательские дизайны были максимально актуальны и соответствовали гайдам и дизайн-системе в целом. А библиотека была синхронизирована с фигмой и гайдами. И проекты, стремящиеся к тому же тоже есть. Плюс, в компании нередко запускаются новые проекты, в которых нет легаси, готовые сразу использовать последние версии дизайн-системы.

Таким образом, необходимо выработать решение, удовлетворяющее всем описанным требованиям:

  • позволяет выпускать визуальные изменения настолько часто, насколько это нужно
  • уменьшает трудоемкость обновления библиотеки на версии с визуальными изменениями
  • позволяет использовать последние визуальные изменения всем желающим
  • не побуждает новые и другие активные проекты использовать неактуальны стили
  • не сильно повышает техническую сложность библиотеки и процесс ее разработки

Решение

В библиотеке появляется версионирование тем, т.е. несколько разных версий одной и той же базовой темы, светлой или темной, с разным набором визуальных изменений. Пользователь может выбрать себе наиболее подходящую в данный момент версию темы, оставаясь при этом на последней версии библиотеки.

Концепт

В LIGHT_THEME и DARK_THEME всегда самые актуальные стили.

Есть промежуточные версии тем, которые можно использовать вместе с последней версией библиотеки (LIGHT_THEME_X, DARK_THEME_X), чтобы не получать визуальные изменения.

Т.е. пользователь устанавливая очередную версию пакета, например, 5.1.0, сможет при желании остаться на предыдущей версии темы, явно ее применив:

import { ThemeContext } from '@skbkontur/react-ui/lib/theming/ThemeContext';
import { LIGHT_THEME_5_0 } from '@skbkontur/react-ui/lib/theming/themes/LightTheme;

<ThemeContext.Provider value={LIGHT_THEME_5_0}>
  <App />
</ThemeContext.Provider>

Переименование

Было Стало
LIGHT_THEME_2022_0 LIGHT_THEME_5_0
LIGHT_THEME_2022_1 LIGHT_THEME_5_1

Создание новых тем

// packages/react-ui/internal/themes/LightTheme5_1.ts

import { createThemeFromClass, markThemeVersion } from '../../lib/theming/ThemeHelpers';

import { BasicThemeClass } from './BasicTheme';
import { LightTheme5_0 } from './LightTheme5_0';

export const LightTheme5_1 = createThemeFromClass(
  class LightTheme5_1Class extends (class {} as typeof BasicThemeClass) {
    public static btnDefaultBg = 'red';
  },
  {
    prototypeTheme: LightTheme5_0,
    themeMarkers: [markThemeVersion(5.1)],
  },
);
// packages/react-ui/lib/theming/themes/LightTheme.ts

import { ThemeFactory } from '../ThemeFactory';
import { LightTheme5_0 } from '../../../internal/themes/LightTheme5_0';
import { LightTheme5_1 } from '../../../internal/themes/LightTheme5_1';

export const LIGHT_THEME_5_0 = ThemeFactory.create({}, LightTheme5_0);
export const LIGHT_THEME_5_1 = ThemeFactory.create({}, LightTheme5_1);

export const LIGHT_THEME = LIGHT_THEME_5_1;

Создание визуальных изменений

Хелпер для определения текущей версии темы. GTE значит "greater than or equal", т.е. больше или равно (>=). Другие, вероятно, не понадобятся из-за композиции версий.

isThemeGTE(theme, 5.0)

Стили

export styles = {
  ...,
  root5_1() {
    return css`
      text-transform: lowercase;
    `;
  },
}

Код компонента. Используем композицию версий, т.е. последующие накладываются на предыдущие.

<Button className={cx(styles.root, isThemeGTE(5.1) && styles.root5_1), isThemeGTE(5.2) && styles.root5_2)} />

Тесты

Делаем истории и скриншоты на предыдущую версию темы с ее отличиями. Используем дефолтный браузер (хром 2022), остальные скипаем, новые не создаем.

// packages/react-ui/internal/ThemePlayground/__stories__/Theme5_0.stories.tsx
import React from 'react';

import { Button } from '../../../components/Button';
import { Story, Meta } from '../../../typings/stories';
import { ThemeContext } from '../../../lib/theming/ThemeContext';
import { LIGHT_THEME_5_0 } from '../../../lib/theming/themes/LightTheme';

export default {
  title: 'ThemeVersions/5.0',
  decorators: [
    (Story) => (
      <ThemeContext.Provider value={LIGHT_THEME_5_0}>
        <Story />
      </ThemeContext.Provider>
    ),
  ],
  parameters: {
    creevey: {
      skip: {
        'no themes': { in: /^(?!\bchrome2022\b)/ },
      },
    },
  },
} as Meta;

export const Button5_0: Story = () => <Button>Button</Button>;
  • базовая или абстрактная тема?
  • добавление новых переменных
  • пример с разной версткой в разных версиях темы
  • версии везде через "_" и переход к "семверному" сравнению
  • как померить пользу

Ссылки

IF-2146

Чек-лист перед запросом ревью

  1. Добавлены тесты на все изменения
    ✅ unit-тесты для логики
    ✅ скриншоты для верстки и кросс-браузерности
    ⬜ нерелевантно

  2. Добавлена (обновлена) документация
    ⬜ styleguidist для пропов и примеров использования компонентов
    ⬜ jsdoc для утилит и хелперов
    ⬜ комментарии для неочевидных мест в коде
    ⬜ прочие инструкции (README.md, contributing.md и др.)
    ✅ нерелевантно

  3. Изменения корректно типизированы
    ✅ без использования any (см. PR 2856)
    ⬜ нерелевантно

  4. Прочее
    ✅ все тесты и линтеры на CI проходят
    ✅ в коде нет лишних изменений
    ✅ заголовок PR кратко и доступно отражает суть изменений (он попадет в changelog)

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

Successfully merging this pull request may close these issues.

1 participant