META
Руководства
Правила при работе с темами приложений

Правила при работе с темами приложений

В этом разделе будет рассматриваться что такое темы приложений и как с ними работать #Темы для приложений. Про то, как стилизовать компоненты под определенные темы приложения #Стилизация компонентов. А также про #Лучшие практики при работе с темами.

Темы для приложений

  1. Исходники тем для приложений - это .less файлы в папке themes src/main/webapp/app/react/src/themes/

Если вы поменяли эти исходники или добавили новые, их нужно сбилдить

make build_themes

или

cd src/main/webapp/app/react
npm run buildThemes

После этого они запишутся как CSS-файлы в папку src/main/webapp/app/contrib/appTheme

  1. Единоразово нужно добавить список тем для конкретного приложения в workspace/production/apps.yaml в таком формате
themeList:
  - name: "Название темы"
    alias: "название-темы"

name - название темы, которое пользователь видит в списке тем

alias - технический алиас темы.  Пишется латиницей через дефис

Для всех тем в CSS используется префикс app-theme. То что прописано в alias используется как постфикс.

Например, alias: "light" соответствует CSS-классу: .app-theme-light.

  1. Единоразово добавить стили в файл src/main/webapp/app/app_styles.ftl для конкретного приложения
[#if app.id == "{currentAppId}"]
    <link href="/contrib/appTheme/{currentAppName}/themes.css" rel="stylesheet" />
[/#if]

Стилизация компонентов

Некоторые компоненты в приложении будут иметь дополнительные стили для определенных тем приложения. Разберем как ими управлять на примере обычной кнопки и двух тем: По умолчанию, light.


Базовый шаблон

Сначала базово разберем структуру проекта:

  1. У нас есть родительский элемент (обычно это <body></body>), на него навешиваются классы которые, обозначают выбранную тему (изначально у приложения выбрана тема "По умолчанию" что соответствует классу app-theme-default).
<body className="app-theme-default">
    ...
</body>
  1. В приложении есть кнопка с классом btn-primary, которая находится внутри родительского элемента.
<button className="btn-primary">
    ...
</button>
  1. Для кнопки btn-primary написаны базовые правила определяющие то как элемент будет выглядеть.
// src/main/webapp/app/style/buttons.less
.btn-primary {
  background-color: @navy;
  border-color: @navy;
  color: #FFFFFF;
 
  ...
}

Работа с темами

Если нужно стилизовать эту кнопку под какую-то из тем, то пишется дополнительное правило для класса он формируется из: темы под которую стилизуется кнопка app-theme-light + класс самой кнопки btn-primary.

Итоговый класс будет выглядеть так: .app-theme-light .btn-primary.

Для этого класса мы пишем те правила, которые должны отличаться от базовых правил в теме light. Мы не переписываем все правила заново, а только добавляем и/или переопределяем правила, которые отличаются в теме light от темы По умолчанию. В данном случаи мы хотим поменять цвет кнопки и ее краев

// themes/light-theme.less
@import 'colors';
 
.app-theme-light {
  
  .btn-primary {
    background-color: @main-bg-color-light-mode;
    border: 1px solid @main-bg-color-light-mode;
  }
}

Теперь для нашей будут действовать одновременно базовые правила и правила написанные под конкретную тему. Но свойства написанные для определенной темы будут перекрывать базовые свойства из-за того что класс с темой приложения .app-theme-light .btn-primary имеет бÓльшую специфичность чем обычный класс btn-primary

// src/main/webapp/app/style/buttons.less
.btn-primary {
  background-color: @navy;
  border-color: @navy;
  color: #FFFFFF;
 
  ...
}
 
---
// themes/light-theme.less
@import 'colors';
 
.app-theme-light {
  
  .btn-primary {
    background-color: @main-bg-color-light-mode; // Это свойство перекрывает свойство написанное в классе .btn-primary
    border: 1px solid @main-bg-color-light-mode; // Это свойство перекрывает свойство написанное в классе .btn-primary
  }
}

Важным моментом является то, что мы никак не меняем свойства прописанные в базовом классе, только лишь добавляем нужные правила под конкретную тему приложения

Лучшие практики при работе с темами

Организация переменных

Рекомендуется использовать CSS/LESS переменные для определения основных цветов и других повторяющихся значений темы:

// themes/colors.less
@main-bg-color-light-mode: #030a12;
@main-text-color-light-mode: #7f7f7f;
 
// themes/light-theme.less
@import 'colors';
 
.app-theme-light {
  font-family:'Source Sans Pro', sans-serif !important;
  background-color: @main-bg-color-light-mode !important;
  color: @main-text-color-light-mode !important;
}

Структура тем

Рекомендуемая структура файлов для тем:

src/main/webapp/app/react/src/themes/
├── primary/
│   ├── colors.less // Переменные с цветами
│   ├── common.less // Общие стили для всех тем
│   ├── dark-theme.less // Стили для темы "Темная"
│   ├── light-theme.less // Стили для темы "Светлая"
│   └── main.less // Основные стили для всех тем
├── secondary/
│   ├── colors.less
│   ├── common.less
│   ├── dark-theme.less
│   ├── light-theme.less
│   └── main.less

primary и secondary - это пример id приложений из файла apps.yaml

Рекомендации по стилизации

  1. Избегайте использования абсолютных значений цветов внутри компонентов. Всегда используйте переменные:
/* Неправильно */
.btn-primary {
    background-color: #499df3;
}
 
/* Правильно */
.btn-primary {
    background-color: @navy;
}
  1. При добавлении новых компонентов убедитесь, что они корректно стилизуются во всех существующих темах.

  2. Старайтесь избегать использования специфичных селекторов, таких как !important.

  3. Старайтесь группировать селекторы тем для оптимизации CSS/LESS:

/* Неправильно */
.app-theme-light .button { /* styles */ }
.app-theme-light .input { /* styles */ }
 
/* Правильно */
.app-theme-light {
    .button { /* styles */ }
    .input { /* styles */ }
}