Что такое компонент
Эта страница определяет компонент, показывает, как он попадает на страницу, из каких частей состоит и как устроен внутри.
Что такое компонент
Компонент даёт готовый, согласованный с темой элемент интерфейса, который не нужно собирать заново на каждой странице. Эта глава определяет компонент и показывает его место среди уровней Framework.
Компонент — повторяемый элемент интерфейса с устойчивой HTML-структурой и готовым оформлением: кнопка, поле ввода, флажок, уведомление, вкладки. Компонент отвечает на вопрос «как этот элемент выглядит и из каких частей состоит».
Компонент не изобретает своих значений. Он собран из того, что описано в предыдущих частях:
- токены дают ему цвета, размеры, радиусы, тени и длительности (см. Токены, цвет и темы и Размер, пространство, текст и форма);
- утилиты раскладывают его части внутри (см. Компонент не раскладывает себя сам);
- собственный CSS связывает токены с частями компонента и задаёт варианты и состояния;
- небольшой JavaScript — там, где без него нельзя: связать подпись с полем, подключить маску ввода, сбросить оформление после сброса формы.
Поэтому смена темы или языка меняет и компоненты: они читают те же токены, что и вся страница.
Место компонента среди уровней Framework:
| Уровень | Что даёт | Пример |
|---|---|---|
| Утилита | Одно свойство | gap-2, flex, elevation-2 |
| Компонент | Структуру и оформление целого элемента | .sf-button, .sf-input |
| Smart-компонент | Поведение, состояние и события поверх тех же классов | <sf-button> |
Компонент не хранит данных и не принимает решений. Значение поля хранит
нативный <input>, отправку формы делает браузер, запрос к серверу — проект.
Смотрите также: Компонент не раскладывает себя сам — раскладка частей компонента; Smart-компоненты — поведение поверх тех же классов.
Как компонент попадает на страницу
Компонент подключается классом в разметке: подключать его файлы вручную не
нужно. Loader (см. Как работает Loader) просматривает страницу и, увидев корневой класс
компонента, подключает его CSS и JavaScript. У каждого компонента есть
правило: например, кнопка подключается, когда в атрибуте class встречается
sf-button, поле — когда встречается sf-input.
<button type="button" class="sf-button sf-button--default sf-button--primary sf-button--size-1">
<span class="sf-button-text-container">Сохранить изменения</span>
</button>
Если разметка появилась позже (например, пришла с сервера), Loader обработает и её.
JavaScript обычного компонента сам находит свои элементы — и уже существующие, и добавленные позже — и привязывается к ним один раз. Например, поле при привязке выдаёт контролу идентификатор и связывает с ним подпись и подсказку (см. Поля формы).
Смотрите также: Как работает Loader — Loader; Как утилиты попадают на страницу — как Loader подключает утилиты.
Анатомия: корень, части, модификаторы, состояния
Каждый компонент описывается одной грамматикой имён. Зная её, вы по классу понимаете, что это — корень, часть, вариант или состояние.
| Что | Как пишется | Пример |
|---|---|---|
| Корень | sf-<компонент> |
sf-button, sf-input, sf-checkbox |
| Часть | sf-<компонент>-<часть> |
sf-button-text-container, sf-input-field, sf-checkbox-box |
| Модификатор | sf-<компонент>--<значение> |
sf-button--outline, sf-button--primary, sf-input--filled |
| Модификатор размера | sf-<компонент>--size-<ступень> |
sf-button--size-1, sf-input--size-1/2 |
| Состояние | короткий класс без префикса или нативный признак | error, active, loading, disabled, :disabled |
| Общие классы | без префикса компонента | sf-icon, spacing-compact, radius-rounded |
Корень — то, что видит Loader и к чему привязано всё остальное. Части
называются через один дефис от имени корня: sf-input-label, sf-input-text,
sf-input-field, sf-input-hint-text-wrap. Модификаторы пишутся через два
дефиса и выбирают вариант. Состояние — отдельное короткое слово: оно не
привязано к компоненту, потому что «ошибка» или «нажато» значат одно и то же
везде.
Пример поля целиком:
<label class="sf-input sf-input--size-1 sf-input--bordered flex flex-col">
<span class="sf-input-label flex"><span class="sf-input-text">Рабочая почта</span></span>
<span class="sf-input-field items-cross-center transition flex">
<i class="sf-icon" aria-hidden="true">mail</i>
<input type="email" name="email" autocomplete="email" placeholder="name@example.com">
</span>
<span class="sf-input-hint-text-wrap">Используем только для уведомлений</span>
</label>
Здесь видно всё сразу: корень sf-input с двумя модификаторами (размер и вид),
части sf-input-label, sf-input-text, sf-input-field,
sf-input-hint-text-wrap, общая иконка sf-icon и утилиты раскладки (flex,
flex-col, items-cross-center, transition).
Утилиты в разметке компонента — часть его структуры. Раскладку частей (строка или колонка, выравнивание) компонент берёт из утилит, а не повторяет в своём CSS. Поэтому в примерах из справочника утилиты стоят прямо на частях компонента, и при переносе их нужно сохранять.
Полный список частей и модификаторов каждого компонента — в разделе «Публичные
классы» его страницы в справочнике компонентов (/ru/components/…).
Смотрите также: Определение — чем утилита отличается от модификатора; Настройки: общий язык компонентов — настройки; Состояния — состояния.
Из чего сделан компонент
Эта глава показывает внутреннее устройство компонента: переменные, через которые варианты и состояния меняют вид, каскадные слои и папку компонента в исходниках.
Переменные компонента
Компонент не пишет цвет или отступ прямо в правило. Каждая часть читает свою переменную, а варианты и состояния только меняют её значение:
.sf-button {
background-color: var(--sf-button--background-color);
}
.sf-button.sf-button--default.sf-button--primary {
--sf-button--background-color: var(--sf-primary);
}
Имя переменной строится от части: --sf-button--background-color,
--sf-input-field--border-color, --sf-checkbox-box--border-color. Значение
берётся из токена: роли цвета (--sf-primary, --sf-outline,
--sf-surface-0), ступени шкалы прозрачности или лестницы размеров. Так вариант, состояние и тема меняют одну переменную и не
спорят друг с другом за свойство.
Переменные бывают двух видов.
- Публичные — несколько переменных, которые компонент предлагает для
настройки: цвета, рамка, скругление, отступы. В имени после блока стоит
один дефис:
--sf-badge-color,--sf-button-radius. Их имена стабильны: переименовать или убрать такую переменную можно только через журнал изменений, с предупреждением. Framework их не задаёт, поэтому значение ставят на сам компонент или на любого предка. Публичные переменные меняют спокойный вид, а наведение, фокус, недоступность и ошибка рисуются поверх, поэтому состояния остаются видны. - Внутренние — все остальные, с двумя дефисами после блока
(
--sf-button--background-color). Это проводка компонента: модификаторы задают им значения, а части их читают. Их имена и устройство могут меняться в любом выпуске, поэтому проект их не задаёт.
/* Кнопки в карточках тарифа — со скруглением побольше */
.pricing-card .sf-button {
--sf-button-radius: var(--sf-radius-circle);
}
На странице компонента публичные переменные собраны в разделе «Переменные → Настройка», внутренние — в «Устройство». Публичные переменные есть не у всех компонентов. Общий вид проекта меняют общие токены, а глубокий вид Smart-компонента — его шаблон (см. Как менять дизайн).
Каскадные слои
Стили компонентов лежат в каскадных слоях Framework (порядок слоёв — см. Каскадные слои):
sf.reset, sf.tokens, sf.base, sf.utilities, sf.components,
sf.overrides, sf.states. Основное оформление — в sf.components, реакции на
наведение, фокус, нажатие и недоступность — в sf.states. Слой состояний стоит
последним, поэтому состояние всегда видно, даже если вариант задан более
длинным селектором.
Папка компонента в исходниках
Это нужно тем, кто читает исходники Framework или пишет компонент для него.
Компонент живёт в src/component/<имя>/:
| Файл или папка | Назначение |
|---|---|
index.js |
Точка входа: подключает стили и скрипт |
rule.js |
Правило Loader: по какому классу подключать |
scss/ |
Стили; index.scss подключает файлы _css__… и, если есть, _var__… |
js/ |
Скрипт компонента, если он нужен |
json/<корень>.utility.json |
Какие утилиты раскладки компонент ставит на свои части (например, buttons/json/button.utility.json), если есть |
docs/docs.md |
Заметки для разработчика: разметка, публичные оси, состояния, если есть |
Опубликованная поставка ui собирается из этих исходников и вручную не
правится (см. Источник и готовые файлы).
Смотрите также: Каскадные слои — каскадные слои; Источник и готовые файлы — поставка.