Иконки и кастомизация узлов

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

В Carbon Components Svelte иконки представлены как отдельные компоненты, импортируемые из пакета @carbon/icons-svelte. Каждый компонент иконки соответствует определённой SVG-графике и может быть встроен в любой элемент интерфейса. Для импорта используется стандартная конструкция ES6:

import Add16 from '@carbon/icons-svelte/lib/Add16.svelte';
import Search20 from '@carbon/icons-svelte/lib/Search20.svelte';

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

Вставка иконки в компонент

Иконки можно использовать внутри любых компонентов, таких как кнопки, меню, формы. Простейший пример вставки:

<Button>
  <Add16 slot="icon" />
  Добавить элемент
</Button>

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

<Add16 class="custom-icon" />

Или через стиль:

<Add16 style="fill: #0f62fe; width: 24px; height: 24px;" />

Кастомизация узлов компонентов

Carbon Components Svelte строится на Svelte-компонентах с детальной возможностью переопределения внутренних узлов через слоты и свойства. Важнейшие подходы к кастомизации:

  1. Слоты для внутренних узлов

Большинство компонентов предоставляют несколько слотов для замены стандартных элементов. Например, компонент DataTable:

<DataTable {rows} {headers}>
  <svelte:fragment slot="table-toolbar-content">
    <Button kind="secondary">Экспорт</Button>
  </svelte:fragment>
</DataTable>

Здесь содержимое слота table-toolbar-content полностью заменяет стандартный блок тулбара.

  1. Переопределение классов и атрибутов

Через свойство class можно добавлять кастомные CSS-классы:

<TextInput
  class="custom-input"
  placeholder="Введите значение"
/>

Для более глубокой кастомизации некоторых компонентов доступно свойство innerProps:

<Button innerProps={{ id: 'my-button', 'aria-label': 'Добавить элемент' }}>
  Добавить
</Button>

innerProps передает произвольные атрибуты напрямую корневому элементу компонента.

  1. Использование пользовательских узлов в DataTable и List

Компоненты с повторяющимися узлами, например таблицы или списки, поддерживают передачу кастомного рендера через функции или слоты. Пример для List:

<List {items}>
  <svelte:fragment slot="item" let:item>
    <div class="custom-list-item">
      <Search20 class="icon" />
      <span>{item.name}</span>
    </div>
  </svelte:fragment>
</List>

Слот item позволяет контролировать каждый элемент списка, вставлять иконки, стилизовать текст или добавлять дополнительные интерактивные элементы.

Динамическая кастомизация и реактивность

Svelte поддерживает реактивные переменные, и Carbon Components Svelte позволяет менять визуальные элементы на лету:

<script>
  import Add16 from '@carbon/icons-svelte/lib/Add16.svelte';
  let isActive = false;
</script>

<Button on:click={() => isActive = !isActive}>
  {#if isActive}
    <Add16 class="active-icon" />
  {/if}
  Статус
</Button>

Такой подход позволяет изменять иконки и стили компонентов в зависимости от состояния приложения без перерисовки всего DOM.

Настройка темы и размеров

Некоторые компоненты поддерживают глобальные переменные CSS для управления цветовой схемой и размерами:

:root {
  --cds-button-compact-padding: 0.5rem 1rem;
  --cds-icon-size: 20px;
}

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

Итоговая схема кастомизации

  • Слоты – основной механизм для замены стандартных узлов.
  • CSS-классы и style – для визуальных изменений.
  • innerProps – для передачи атрибутов корневому элементу.
  • Реактивные переменные Svelte – для динамического управления контентом.
  • Глобальные CSS-переменные – для унифицированной настройки темы и размеров компонентов и иконок.

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