Дизайн-система как инструмент для разработчика

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Привет! Я – Лера Егорова, frontend-разработчик в Мир Plat.Form. Про дизайн-системы чаще пишут дизайнеры – и это понятно. Но, так как первый кирпич в создании нашей собственной дизайн-системы был заложен со стороны разработки, то хотелось бы рассказать о ней со своей колокольни. Собранная «на коленке» дизайн-система со временем обросла интересными фишками и инструментами для разработчика. О том, какими, читайте под катом.

Немного о том, как устроена наша дизайн-система

Дизайн-система, как известно, это комплексное понятие. В него входит и UI-кит, и правила, и библиотека компонентов. Здесь речь пойдет о приложении, в котором всё это собрано. Его создание стало жизненной необходимостью, так как в стилях был бардак, то и дело всплывали баги, на разных страницах одни и те же элементы отображались по-разному. Хотелось просто систематизировать элементы и навести порядок, поэтому было решено все стили и библиотеку компонентов вынести в отдельное приложение.

В моем распоряжении был UI-кит и библиотека компонентов PrimeNG для Angular, которую мы используем в наших проектах. Получившаяся в итоге дизайн-система — это, по сути, такое же приложение, как и все остальные наши проекты, только со всеми используемыми элементами, разложенными по полочкам. Вся верстка теперь производится в дизайн-системе, а получившиеся стили и библиотека подтягиваются в проекты через зависимости.

Для себя любимых

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

Использование настроек и копирование кода
Использование настроек и копирование кода

Одна тема – маловато будет!

Обычно, когда говорят о дизайн-системе, предполагают использование единого UI-кита для многих приложений. И, действительно, большинство наших проектов похожи друг на друга как братья и сестры. Но, как правило, очень часто находится приложение, которое не хочет быть «как все» и разительно отличается от остальных. У нас таким оказался MIR Design – автоматизированная система сертификации дизайна и тиража карт. Оставлять его за бортом дизайн-системы не хотелось, поэтому под этот проект была создана отдельная тема (подразумевается даже собственный UI-кит, так как отличалось всё – от цветов до расстояний).

Так, например, выглядит таблица в одном из типичных, похожих друг на друга, проектов:

А так в MIR Design:

В самой дизайн-системе появился переключатель тем. Принцип его работы довольно прост. У каждой темы есть своя папка со стилями, а переключатель в интерфейсе просто меняет класс у body. Так темы существуют независимо друг от друга. С названиями для тем я не стала заморачиваться и просто их пронумеровала: в итоге получились тема №1 и тема №2.

.theme-1 {
  @import "assets/themes/theme-1/theme-1";
}

.theme-2 {
  @import "assets/themes/theme-2/theme-2";
}

Несмотря на один существенный недостаток мультитемности – для каждой новой темы нужно создавать и поддерживать стили – такой подход в итоге окупился. Теперь для новых приложений есть выбор, а у нас появились и другие проекты с темой от MIR Design.

Позже появилась и третья тема. Начались работы над внутренним приложением для сотрудников (преимущественно для разработчиков) и использовать существующие темы очень не хотелось, так как программисты и так каждый день работают с кучей одинаковых приложений. Чтобы не путать проекты для внутренних и внешних клиентов, была разработана новая, не похожая на остальные, тема. У нее также появились последователи в виде других внутренних приложений, так что одиноких проектов у нас нет. Да и дизайнерам развлечение – они не заперты в рамках одного UI-кита.

Так работает переключатель тем
Так работает переключатель тем

Лень – двигатель прогресса: конструкторы

Наши приложения в основном состоят из форм различной конфигурации и таблиц. Как-то, собирая интерфейс страниц из элементов дизайн-системы для очередного нового проекта, я устала от однотипной работы, и решила ускорить процесс. Буквально за пару дней для дизайн-системы были написаны конструкторы для форм и таблиц, которые генерируют не только разметку, но и базовую логику, а также заготовку для словарей (практически все наши проекты поддерживают 2 языка – русский и английский). С тех пор таблицы и формы стали создаваться за считанные минуты.

Интерфейс для конструктора форм
Интерфейс для конструктора форм

Вот пример кода, который генерирует конструктор для форм:

1) HTML:

<form [formGroup]="form" class="form-horizontal form-sm">

  <div class="p-fluid">
    <div class="p-field">
      <label for="name1">{{ 'name1' | translate: pointer | ucfirst }}</label>
      <div>
        <input type="text" pInputText id="name1" [formControlName]="'name1'">
        <ctms-common-validator-message [field]="this.form.get('name1')"></ctms-common-validator-message>
      </div>
    </div>
    <div class="p-field">
      <label for="name2">{{ 'name2' | translate: pointer | ucfirst }}</label>
      <div>
        <p-dropdown [options]="items" id="name2" [formControlName]="'name2'"></p-dropdown>
        <ctms-common-validator-message [field]="this.form.get('name2')"></ctms-common-validator-message>
      </div>
    </div>
  </div>

  <div class="flex mt32">
    <button pButton type="button" label="{{ 'cancel' | translate: 'COMMON' | ucfirst }}" class="p-button-outlined mr16" (click)="doCancel()"></button>
    <button pButton type="button" label="{{ 'button_save' | translate: 'COMMON' | ucfirst }}" (click)="doSubmit()"></button>
  </div>

</form>

2) Код для класса компонента - инициализация реактивной формы и заготовки методов:

export class FormDemoComponent implements OnInit {

  pointer = 'FORM';
  form : FormGroup;
  items: SelectItem[];

  constructor(private formBuilder: FormBuilder) {}

  ngOnInit(): void {
    this.form = this.formBuilder.group({
      name1: ['', [Validators.required]],
      name2: ['', [Validators.required]],
  });
  }

  doCancel() {
  }

  doSubmit() {
  }

}

3) Заготовка для словаря:

import {Dictionary} from "@_/ctms-common-module";

export default <Dictionary> {
  "FORM": {
    "en": "",
    "ru": "",
    "name1": {
      "en": "name1",
      "ru": "name1",
    },
    "name2": {
      "en": "name2",
      "ru": "name2",
    },
  }
}

В итоге, не написав ни строчки кода, получаем такого вида форму, мультиязычную, с работающей валидацией:

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

Недалёкое (ну я надеюсь!) будущее

Приложение для дизайн-системы продолжает развиваться и всё время руки чешутся внедрить в него ещё какие-нибудь фишки для ускорения своей работы. Делюсь некоторыми из наших планов.

Конструктор для тем

Хочется верить, что имеющимися тремя темами дело и ограничится, но жизнь распоряжается по-своему. И то и дело возникают ситуации, когда всенепременно нужна новая тема. Так может и не стоит ограничивать полёт фантазии дизайнеров, а создать универсальный инструмент, который через интерфейс позволяет без труда создавать новые варианты. Ведь библиотека и набор элементов, как правило, остаются теми же, отличаются только оформительские свойства в стилях. Задача создания этого конструктора не тривиальна, но попробовать очень хочется.

Отдельные режимы для дизайнеров и разработчиков

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

Обучающий тренажер

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

В идеале, конечно, будем надеяться, что когда-нибудь мы изобретем волшебную кнопку, которая делает всё за нас (мечты, мечты…), а пока будем автоматизировать рутинные действия, чтобы уделять больше внимания наиболее сложным и интересным задачам.

Источник: https://habr.com/ru/company/nspk/blog/673898/


Интересные статьи

Интересные статьи

Впервые я столкнулся с техническими собеседованиями еще в 2012 году, когда искал свою первую работу в IT. Я выслушал условия задачи, нацарапал решение на доске, ответил на несколько вопросов и ушел, в...
Я работаю Java/Kotlin-разработчиком в компании EPAM. В этой статье хочу поделиться опытом настройки плагина ktlint для Kotlin проекта. Данный плагин помогает об...
Когда в моей компании разрешили снова работать в офисе, я понял, что во мне живет два разных сотрудника — домашний и офисный. У них разная производительность. В офисе я сконцентрирова...
Недавно на Хабр вышел перевод статьи «Оцениваем рекрутеров по холодным письмам». Примечание переводчика и 120 комментариев показывают, что тема болезненна для русскоязычных разработчиков, а рынок...
Всем привет! Я бэкэнд-разработчик, пишу микросервисы на Java + Spring. Работаю в одной из команд разработки внутренних продуктов в компании Тинькофф. У нас в команде часто встает вопрос оптими...