Создание и документирование компонентов пользовательского интерфейса

Storybook - это инструмент с открытым исходным кодом для разработки компонентов пользовательского интерфейса изолированно для React, Vue, Angular и других. Это делает создание потрясающих пользовательских интерфейсов организованным и эффективным.

Storybook предлагает множество замечательных готовых функций, которые помогают нам при работе над компонентами пользовательского интерфейса. Он предоставляет «песочницу» для их изолирования, чтобы мы могли разрабатывать их полностью вне контекста. Таким образом, мы можем протестировать несколько вариантов использования, в которых он может использоваться, и различные сценарии его поведения; упрощая поиск сложных крайних случаев.

Более того, он также предоставляет функции, которые значительно облегчают документирование этих компонентов. Это упрощает обмен ими с другими командами и показывает, как их можно использовать и когда следует. Он также поддерживает Markdown и MDX, что позволяет нам создавать надежную документацию и руководства по стилю.

С помощью Storybook вы создаете истории для своих компонентов. Каждая история показывает поведение отдельного компонента с определенным набором состояний.
Здесь мы увидим, как использовать Storybook в проекте Angular, а также узнаем, как он работает и его функции.

Установка Storybook

Добавить Storybook в проект Angular довольно просто.
Сначала мы запускаем команду ниже, чтобы установить Storybook в наш проект, уже инициализировав и настроив его.

npx -p @storybook/cli sb init --type angular

В нашем package.json мы видим, что были добавлены некоторые скрипты:

Чтобы запустить Storybook локально, просто запустите:

npm run storybook 

Мы также видим, что в нашем корневом каталоге создана папка /.storybook. Это файлы конфигурации для Storybook, на которые следует обратить внимание при изменении глобальных настроек.

obs: в файле конфигурации main.js Storybook, вы можете видеть, что он настроен на поиск файлов «* .stories.ts» во всем проекте, поэтому вы можете создавать свои истории, где вы считаете, что они лучше подходят для вашего приложения.

Он также добавляет папку / stories, которая дает нам несколько примеров использования Storybook, предоставляя компоненты, которые были созданы и задокументированы с ее помощью.

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

Создание компонента

Здесь мы собираемся создать простой компонент Link; который будет простым якорем с некоторыми настраиваемыми стилями для учебных целей.

Начнем с создания с помощью интерфейса командной строки Angular.

ng generate component components/link

Создание истории

Теперь, когда у нас есть компонент, мы собираемся создать для него Story. Итак, давайте создадим stories / link.stories.ts, как показано ниже.

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

import { CommonModule } from '@angular/common';
import { moduleMetadata } from '@storybook/angular';
import { Story } from '@storybook/angular/types-6-0';
import { LinkComponent } from '../link.component';
// This exports the Stories group for this component
export default {
  // The title defines the name and where in the structure of
  // Storybook's menu this is going to be placed.
  // Here we add it to a "Components" section under "Link"
  title: 'Components/Link',
  // The component related to the Stories
  component: LinkComponent,
  decorators: [
    // The necessary modules for the component to work on Storybook
    moduleMetadata({
      declarations: [LinkComponent],
      imports: [CommonModule],
    }),
  ],
};
// This creates a Story for the component
const Template: Story<LinkComponent> = () => ({
  component: LinkComponent,
  template: `<app-link></app-link>`,
});
export const Base = Template.bind({});
// Other stories could be added here as well, all you have to do is export them along!

Теперь у нас есть наш компонент и его история! При запуске Storybook это то, что в настоящее время будет генерировать этот код для нас.

Работаем над нашим компонентом

Теперь, когда наш компонент и его история созданы, мы запустим Storybook.

npm run storybook

Когда Storybook запущен, изменения, внесенные в наш компонент, будут обновляться в реальном времени, и поэтому мы можем работать с ним изолированно и тестировать его функциональность и стили в Canvas таб.

Итак, сначала давайте дадим нашему компоненту некоторые свойства:

// link.component.ts
(...)
export class LinkComponent {
  
  @Input()
  color: 'primary' | 'secondary' = 'primary';
  @Input()
  href: string;
  @Input()
  target?: '_self' | '_blank' | '_parent' | '_top' = '_self';
  
  public get classes(): Array<string> {
    return ['link', `${this.color}-link`];
  }
}

Затем мы меняем его шаблон, чтобы отобразить наши свойства.

// link.component.html
<a
  [ngClass]="classes"
  [href]="href"
  [target]="target"
>
  <ng-content></ng-content>
</a>

Наконец, давайте добавим к нему несколько стилей!

// link.component.scss
.link {
  text-decoration: none;
  border-bottom: 1px dotted;
  @media screen and (min-width: 600px) {
    font-size: 1.15em;
  }
}
.primary-link {
  color: #ff4785;
  border-color: #ff4785;
}
.secondary-link {
  color: #1ea7fd;
  border-color: #1ea7fd;
}

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

// stories/link.stories.ts
(...)
const Template: Story<LinkComponent> = () => ({
  component: LinkComponent,
  props: {
    color: 'primary',
    content: 'Visit Storybook',
    href: 'https://storybook.js.org/',
    target: '_blank',
  },
  template: `
    <app-link
      [color]="color"
      [href]="href"
      [target]="target"
    >
      {{ content }}
    </app-link>`,
});
export const Base = Template.bind({});

А теперь мы можем проверить окончательный результат в Storybook!

Изучение сборника рассказов

Есть несколько очень интересных инструментов, которые помогут нам при работе над нашим компонентом в Canvas.

Мы можем изменить цвет фона, чтобы имитировать светлый / темный режимы.

Мы также можем переключать сетку.

Очень важной является возможность изменять размеры области просмотра, чтобы проверить поведение компонентов на небольших экранах. Например, нам может пригодиться проверка изменений font-size нашего компонента для небольших экранов, как показано ниже.

В правом углу у нас есть две интересные иконки.
Первая - развернет выбранную в данный момент историю на весь экран.
Вторая - откроет ее в пустом окне iframe в другом окне.

Установка дополнений

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

Дополнения могут предоставить множество полезных функций при разработке и документировании с помощью Storybook. Чтобы увидеть, как мы можем ими воспользоваться, мы установим и воспользуемся одним из самых популярных: надстройка кнопок.

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

Начнем с установки в нашем проекте.

npm install @storybook/addon-knobs --save-dev

В файле конфигурации main.js Storybook вы регистрируете надстройки и куда мы собираемся добавить новый установленный надстройку, как показано ниже.

// .storybook/main.js
module.exports = {
  "stories": [
    "../src/**/*.stories.mdx",
    "../src/**/*.stories.@(js|jsx|ts|tsx)"
  ],
  "addons": [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/addon-knobs"
  ]
}

И теперь наш аддон готов к использованию!
Важно отметить, что имеет значение порядок в массиве аддонов. Для тех, кто отображается на панели дополнений, порядок будет соответствовать установленному там порядку.

obs: вы можете отметить здесь полный список дополнений и выбрать те, которые хотите установить и использовать в своих историях!

Использование дополнений

Мы собираемся использовать текст и выбор из дополнительных кнопок. < br /> Они собираются установить значение ngContent и color props для нашего компонента динамически при запуске Storybook.
Теперь давайте откроем историю нашего компонента и добавим к нему ручки addon.

// stories/link.stories.ts
import { withKnobs, text, select } from '@storybook/addon-knobs';
export default {
  title: 'Components/Link',
  component: LinkComponent,
  decorators: [
    moduleMetadata({
      declarations: [LinkComponent],
      imports: [CommonModule],
    }),
    // we add the withKnobs decorator in order to use it
    withKnobs,
  ],
};
const Template: Story<LinkComponent> = () => ({
  component: LinkComponent,
  props: {
    // we use the select knob to set the color value
    color: select('Color', ['primary', 'secondary'] , 'primary'),
    // we use the text knob to set the ngContent value
    content: text('Text', 'Visit Storybooks'),
    href: 'https://storybook.js.org/',
    target: '_blank',
  },
  template: `
    <app-link
      [color]="color"
      [href]="href"
      [target]="target"
    >
      {{ content }}
    </app-link>`,
});
export const Base = Template.bind({});

Благодаря этому наши ручки успешно настроены, и мы можем проверить их при запуске Storybook.

// The first parameter is a label for that knob
// The second parameter is its default value
text('Text', 'Visit Storybooks')
// The first parameter is a label for that knob
// The second parameter is the available options to be chosen
// The third parameter is its default value
select(
  'Color',
  ['primary', 'secondary'],
  'primary'
),

Теперь мы видим, что у нас есть новая вкладка (Ручки) для нашей истории.
Они заполнены значениями по умолчанию, которые мы предоставили, но когда мы их изменим, они будут динамически отражаться в нашем визуализированном компоненте!

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

Документирование компонента

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

Как показано в файле Introduction.stories.mdx, поставляемом с установкой, Storybook поддерживает файлы .mdx. С его помощью мы можем быстро создавать страницы, используя элементы markdown и html. Следовательно, мы можем легко использовать его для добавления документации к нашему компоненту.

Итак, давайте создадим новый файл stories / link.stories.mdx, как показано ниже.

import { Meta } from '@storybook/addon-docs/blocks';
<!-- This tells Storybook where to add this content -->
<!-- Here we want it along with our link component -->
<Meta title="Components/Link/Documentation" />
<style>{`
  #colors {
    margin: 20px 0px;
  }`
`}</style>
# Link
Links allow users to navigate to a different location.
(... Lorem Ipsum ...)
## Colors
### Primary
(... Lorem Ipsum ...)
### Secondary
(... Lorem Ipsum ...)

Само содержание представляет собой всего лишь lorem ipsum для учебных целей, но ниже мы можем увидеть, чего мы могли бы достичь с его помощью.

Проверяю!

Когда мы закончим работу, мы можем сгенерировать нашу сборку Storybook, запустив:

npm run build-storybook

Внутри папки '/ storybook-static' будет сгенерировано статическое приложение, которое можно где-нибудь опубликовать, если вам нужно!

obs: при создании сборки Storybook она создает и выводит скомпилированные файлы в «/ storybook-static», поэтому не забудьте добавить их в .gitignore.

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

Визуальное регрессионное тестирование

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

Storybook - отличный инструмент, который можно использовать вместе с инструментами визуального регрессионного тестирования. Большинство из них поставляются с интеграцией Storybook (например, Loki, Percy и Chromatic, последний из которых разработан командой Storybook), и в целом это очень удобно. легко использовать!

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

Надеюсь, это поможет! 😉

использованная литература