Архитектура компонентной библиотеки

Компонентная библиотека в SvelteKit строится вокруг повторно используемых UI-компонентов, которые инкапсулируют логику и стили. Архитектура таких библиотек обычно включает следующие уровни: базовые компоненты, композиционные компоненты, тема и стили, утилиты и хелперы.

Базовые компоненты

Базовые компоненты — это строительные блоки интерфейса: кнопки, инпуты, чекбоксы, модальные окна, тултипы. Они должны быть максимально универсальными и независимыми от контекста приложения.

Ключевые принципы разработки базовых компонентов:

  • Изоляция стилей: использование scoped CSS или CSS-модулей, чтобы компоненты не ломали внешний дизайн.
  • Контролируемые свойства: каждый компонент принимает props, которые задают состояние, внешний вид и поведение. Например, <Button size="large" variant="primary" disabled={true} />.
  • События и обратные вызовы: компоненты должны поддерживать кастомные события через createEventDispatcher для взаимодействия с родительским кодом.

Пример базового компонента кнопки в SvelteKit:

<script lang="ts">
  import { createEventDispatcher } from 'svelte';
  export let size: 'small' | 'medium' | 'large' = 'medium';
  export let variant: 'primary' | 'secondary' = 'primary';
  export let disabled: boolean = false;
  const dispatch = createEventDispatcher();

  function handleClick(event: MouseEvent) {
    if (!disabled) dispatch('click', event);
  }
</script>

<button class={`btn ${size} ${variant}`} on:click={handleClick} disabled={disabled}>
  <slot />
</button>

<style>
  .btn { padding: 0.5rem 1rem; border-radius: 4px; }
  .small { font-size: 0.8rem; }
  .medium { font-size: 1rem; }
  .large { font-size: 1.2rem; }
  .primary { background-color: #0070f3; color: white; }
  .secondary { background-color: #eaeaea; color: #333; }
  button:disabled { opacity: 0.5; cursor: not-allowed; }
</style>

Композиционные компоненты

Комплексные интерфейсные элементы строятся на основе базовых компонентов. Например, формы, карточки, таблицы данных состоят из комбинации кнопок, инпутов, чекбоксов и тултипов.

Особенности композиционных компонентов:

  • Передача props вниз: родительский компонент управляет состоянием дочерних компонентов.
  • Слоты и фрагментация контента: использование <slot> позволяет вставлять произвольный контент, делая компонент гибким.
  • Управление состоянием: можно использовать локальные состояния или Svelte store для синхронизации данных между элементами.

Пример карточки с кнопкой и текстом:

<Card>
  <h3 slot="header">Заголовок карточки</h3>
  <p slot="body">Описание элемента</p>
  <Button slot="footer" variant="primary">Действие</Button>
</Card>

Тема и стили

Компонентные библиотеки в SvelteKit используют систему темизации, которая позволяет задавать глобальные цвета, типографику и отступы.

  • CSS-переменные: определяют основные цвета и размеры (--color-primary, --spacing-base).
  • Тематические файлы: отдельные Svelte-компоненты или модули SCSS, которые импортируются в библиотеку.
  • Динамическая смена темы: можно переключать темы на лету, изменяя значения CSS-переменных в корневом элементе приложения.

Пример переменных темы:

:root {
  --color-primary: #0070f3;
  --color-secondary: #eaeaea;
  --font-size-base: 16px;
  --spacing-base: 1rem;
}

Утилиты и хелперы

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

  • Классовые утилиты (clsx, classnames) для динамического формирования классов.
  • Функции форматирования для дат, чисел, валют.
  • Сторы Svelte для управления глобальным состоянием темы, модальных окон, уведомлений.

Пример использования стор для управления модальным окном:

import { writable } from 'svelte/store';

export const isModalOpen = writable(false);

// В компоненте
<script lang="ts">
  import { isModalOpen } from './stores';
</script>

<button on:click={() => isModalOpen.set(true)}>Открыть модалку</button>
<Modal bind:open={$isModalOpen}>Контент модалки</Modal>

Организация файловой структуры

Для больших библиотек структура играет ключевую роль. Рекомендуется делить на модули:

src/
  components/
    base/
      Button.svelte
      Input.svelte
    composite/
      Card.svelte
      Form.svelte
  styles/
    theme.css
    variables.css
  utils/
    formatters.ts
    classnames.ts
  stores/
    themeStore.ts
    modalStore.ts

Такое разделение упрощает поддержку, повторное использование и масштабирование библиотеки.

Интеграция с SvelteKit

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

  • Экспорт компонентов через единый index.ts для удобного импорта:
export { default as Button } from './base/Button.svelte';
export { default as Card } from './composite/Card.svelte';
  • Использование динамического импорта для больших компонентов, чтобы уменьшить размер начальной загрузки.
  • Поддержка SSR и гидратации через корректную инициализацию состояния и обработку событий в браузере.

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