Фабрики компонентов

FAST Element — это современная библиотека для построения веб-компонентов на базе стандарта Web Components с расширениями для удобной работы с шаблонами, реактивными свойствами и стилями. Центральной концепцией является использование фабрик компонентов для создания переиспользуемых и настраиваемых элементов. Фабрика позволяет инкапсулировать логику создания компонента и его шаблона, обеспечивая гибкость при интеграции и настройке.


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

Фабрика компонента в FAST Element создаётся с помощью функции FASTElement.define() или через html/css шаблоны и композицию классов. Основная задача — объединить:

  • Класс компонента, наследующий FASTElement.
  • HTML-шаблон, описывающий разметку компонента.
  • CSS-стили, локализованные для компонента.

Пример базовой фабрики:

import { FASTElement, html, css } from "@microsoft/fast-element";

const template = html<MyButton>`
  <button class="btn">
    <slot></slot>
  </button>
`;

const styles = css`
  .btn {
    padding: 0.5rem 1rem;
    border-radius: 4px;
    border: none;
    background-color: #0078d4;
    color: white;
    cursor: pointer;
  }
`;

class MyButton extends FASTElement {
  // Реактивные свойства
  label = "";
}

FASTElement.define({
  name: "my-button",
  template,
  styles,
  elementClass: MyButton
});

В этом примере фабрика создаёт элемент <my-button> с шаблоном и стилями, полностью изолированными от внешнего DOM.


Использование параметризованных фабрик

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

function createCardComponent(backgroundColor) {
  const template = html`
    <div class="card">
      <slot></slot>
    </div>
  `;

  const styles = css`
    .card {
      padding: 1rem;
      border-radius: 6px;
      background-color: ${backgroundColor};
      box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    }
  `;

  class Card extends FASTElement {}

  return FASTElement.define({
    name: `card-${backgroundColor.replace("#","")}`,
    template,
    styles,
    elementClass: Card
  });
}

createCardComponent("#f0f0f0");
createCardComponent("#ffd700");

Каждый вызов createCardComponent создаёт новый уникальный компонент с индивидуальными стилями. Это особенно удобно при генерации библиотек компонентов с разными визуальными темами.


Фабрики и слоты

FAST поддерживает слоты и вложенные компоненты. Фабрика может автоматически оборачивать слоты для гибкой композиции:

const template = html<MyPanel>`
  <section class="panel">
    <header><slot name="header"></slot></header>
    <main><slot></slot></main>
  </section>
`;

class MyPanel extends FASTElement {}

FASTElement.define({
  name: "my-panel",
  template,
  elementClass: MyPanel
});

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


Реактивные свойства и фабрики

Фабрики упрощают интеграцию реактивных свойств. В FAST реактивное свойство объявляется с помощью @attr или стандартного объявления класса. Фабрика обеспечивает автоматическое связывание этих свойств с шаблоном.

import { FASTElement, html, attr } from "@microsoft/fast-element";

const template = html<MyBadge>`
  <span class="badge">${x => x.count}</span>
`;

class MyBadge extends FASTElement {
  @attr count = 0;
}

FASTElement.define({
  name: "my-badge",
  template,
  elementClass: MyBadge
});

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


Комбинирование фабрик компонентов

FAST поддерживает композицию компонентов, позволяя фабрикам создавать сложные UI из более мелких компонентов. Например, фабрика Card может использовать фабрику Button внутри шаблона:

const cardTemplate = html`
  <div class="card">
    <slot name="content"></slot>
    <my-button>Click Me</my-button>
  </div>
`;

class CardComponent extends FASTElement {}

FASTElement.define({
  name: "custom-card",
  template: cardTemplate,
  elementClass: CardComponent
});

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


Динамическая регистрация компонентов

Фабрики также поддерживают динамическую регистрацию, что полезно при ленивой загрузке компонентов или генерации множества вариаций:

async function loadComponent(name, template, styles, elementClass) {
  if (!customElements.get(name)) {
    FASTElement.define({ name, template, styles, elementClass });
  }
}

loadComponent("lazy-button", html`<button>Lazy</button>`, css`button {color:red}`, class extends FASTElement {});

Динамическая регистрация предотвращает ошибки повторного объявления и позволяет управлять компонентами на лету.


Особенности фабрик FAST Element

  • Инкапсуляция: каждая фабрика создаёт компонент с собственным шаблоном и стилями.
  • Повторное использование: шаблон и логика могут применяться к разным конфигурациям.
  • Реактивность: свойства автоматически синхронизируются с DOM.
  • Композиция: компоненты можно вкладывать друг в друга через слоты и фабрики.
  • Динамичность: поддержка создания компонентов во время выполнения программы.

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