# Компоненты

Расположение компонентов в проекте: source/scss/components.

Компонент - это структурированный, независимый SASS модуль с внутренним API, задача которого вернуть конечные CSS стили или предоставить API для использования другими компонентами.

В среде разработки, каждый компонент - генерирует собственный скомпилированный CSS файл стилей. Для создания конечного файла стилей, используется релиз, который позволяет сгенерировать один и более компонентов в единый файл стилей.

# Вступление

Прежде чем мы начнем разбирать структуру компонента, необходимо принять к сведению основное требование к которому необходимо придерживаться, а именно - разделение логики от стилей (то, что генерируется в правила CSS)!

Для того, чтобы придерживаться данного правила, необходимо ясно понимать, на каком этапе осуществляется SCSS логика (переменные, функции, миксины), а в какой момент, будут сгенерированы CSS правила стилей. Для выполнения данного правила, компонент имеет собственную структуру файлов и минимальные требования для её расширения.

# Почему это важно?

Компоненты выполняют две роли:

  • служат для генерации конечных CSS стилей
  • служат в роли модуля для других компонентов

Если в первом случае все понятно, то во втором может возникнуть вопрос, зачем? Затем, чтобы можно было использовать функционал другого компонента (конфигурацию, миксины, функции)!

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

// components/app/render.scss
@use "ungic.component" as this;
@use "ungic.components.grid" as grid;

@include this.component {
	.btn {
		...
		display:block;
		// Использование @media API компонента grid
		@include grid.media(grid.media(max-xs)) {
			display:none;
		}
	}
}

Так вот, в случае включения компонента в виде модуля, мы бы не хотели, чтобы компонент grid вернул CSS правила всей grid системы, которые будут включены в наш компонент, а в случае, если оба компонента будут включены в один проект, то произойдет дублирование стилей!

TIP

При создании компонента, необходимо соблюдать требование разделения логики от правил которые генерируются в CSS стили!

# Структура компонента:

В данном разделе описывается структура файлов компонента, для ознакомления с внутренним API компонента, обратитесь к соответствующему разделу.

Структура компонента по умолчанию:

.
|─ .core
|─ index.scss
---------------
|─ render.scss
|─ config.scss
|─ properties.scss
|─ once.scss
---------------
|─ mixins
└─ functions

# Компонент состоит из:

Обязательных сущностей:

  • .core - ядро компонента (внутренний API компонента).
  • index

Опциональных:

  • render
  • config.scss
  • properties.scss
  • once.scss

Пользовательских:

  • mixins
  • functions
  • ...

Любой файл или директория с index.scss могут быть частью модуля компонента. По умолчанию, компонент уже имеет миксины и функции.

Обратите внимание!

В случае удаления mixins или functions из компонента, следует удалить их использование из render.scss файла:

//render.scss
@use "ungic.component" as this;
// или @use ".core"as this;

@use "ungic.theme"as theme;

//@use "functions"as *;
//@use "mixins"as *;

...

# Ядро компонента (.core)

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

Включение ядра компонента осуществляется одним из способов:

  • Относительным путем @use "./.core" as this
  • Абсолютным @use "ungic.component" as this
// Относительное включение модуля
@use "./.core" as this;

// Абсолютное
@use "ungic.component" as this;

TIP

Концепция использования ядра компонента очень похожа на использование this в ООП:

@use "ungic.component" as this;

@debug this.cid(); // app
@debug this.config(key); // Конфигурация текущего компонента
@debug this.prop(border); // CSS св-во данного компонента

Ссылки по теме:

# index.scss

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

Данный файл отвечает за "передачу" данных модуля с помощью @forward директивы, а также, для настройки сборки компонента в режиме разработки. Именно этот файл будет включаться в случае использования компонента как модуль.

Содержимое файла по умолчанию:

@forward ".core";

При включении компонента с подобным index.scss файлом с помощью @use директивы, можно получить доступ исключительно к внутреннему API компонента:

// components/ara/render.scss

@use "ungic.components.petya" as petya;

@debug petya.cid(); // petya

Для того, чтобы можно было получить доступ к пользовательским методам компонента, их требуется "переслать" с помощью @forward директивы в index.scss файле компонента:

@forward ".core";
@forward "functions";
@forward "mixins";

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

// components/ara/render.scss
@use "ungic.components.petya" as petya;

// Включение пользовательских функций компонента как модуль
@use "ungic.components.petya.functions" as petya_func;

@debug petya_func.last_name(); // pupkin

# Конфигурация сборки компонента в режиме разработки

Речь идет о конфигурации build.plugins.scss.dev параметра конфигурации scss плагина. В режиме разработки, данную конфигурацию можно определять индивидуально для каждого компонента в index.scss файле с помощью следующего синтаксиса:

// index.scss

/* ::::
inverse: false
autoprefixer: true
theme: darkela
*/

@forward ".core";

Данная возможность позволяет в реальном времени изменить тему компонента или включить / отключить режим генерации инверсии компонента!

# Правила стилей (render.scss)

Опциональное присутствие.

Данный файл должен содержать конечные CSS правила стилей которые будут сгенерированы в CSS.

render.scss файл - это единственный системный файл компонента который должен возвращать css правила стилей! Это не значит, что все стили должны быть написаны именно в render.scss, нет! Структура файлов для написания стилей может быть абсолютно любой, но конечный результат должен быть включен непосредственно в render.scss файл!

Внимание!

render.scss - основной и единственный системный файл компонента который должен возвращать CSS правила стилей!

TIP

Структура файлов для написания стилей может быть любой, но конечный результат должен быть включен непосредственно в render.scss файл!

# Разделение правил на части

Разделение правил на части с последующим включением в render.scss является хорошей практикой, так как, эти части могут быть включены и другими компонентами:

// Структура вымышленного modal компонента
.
|─ .core
|─ index.scss
|─ render.scss
└─ includes
		├─ header.scss
		├─ body.scss
		├─ controls.scss
		└─ footer.scss
// components/modal/render.scss
@use "ungic.component" as this;
@use "sass:meta";

@include this.component {
	@include meta.load-css("./includes/header.scss");
	@include meta.load-css("./includes/body.scss");
	@include meta.load-css("./includes/controls.scss");
	@include meta.load-css("./includes/footer.scss");
}
// Содержимое одного из includes файла
// может выглядеть следующим образом:

// components/modal/includes/header.scss
@use "ungic.utils" as utils;

// Инструмент для объединения селектора с предыдущим
@include utils.merge {
	&-header {
		...
	}
}

Результат CSS будет следующим:

.modal-header {
	...
}
.modal-footer {
	...
}
// и тд

Таким образом, части modal компонента, могут быть использованы и в других компонентах, например для вымышленного panel компонента:

// components/panel/render.scss

@use "ungic.component" as this;

@include this.component {
	@include meta.load-css("ungic.components.modal.includes.header");
}

Результат CSS будет следующим:

.panel-header {
	...
}

Обратите внимание!

Стоит учесть тот факт, что все правила (стили) включенные одним компонентом из другого компонента, будут иметь стиль исходного компонента!

# Экспортирование данных (once.scss)

Опциональное присутствие.

Once.scss - файл служит местом для экспорта данных из SASS. Компиляция компонентов в среде разработки происходит в несколько этапов (в случае генерации инверсии темы), что порождает повторное компилирование .scss файлов компонента (именно поэтому в консоли дважды отображаются sass @debug результаты), исключением является once.scss файл, который включается один раз за весь цикл компиляции.

Экспортированные данные можно включить в виде объекта данных при генерации шаблонов, а также, все данные сохраняются в exports/sass-options.json файле в JSON формате.

// components/test/once.scss

@use ".core" as this;

$data: (
	as_number: 1,
	as_str: 'Lorem ipsum',
	as_map: (
		name: 'Artem'
	),
	as_boolean: true,
	as_color: #FFF
);
$export: this.export('data', $data);
// dist/exports/sass-options.json
{
	"oid": "data",
	"cid": "test",
	"data": {
		"as_number": 1,
		"as_str": "Lorem ipsum",
		"as_map": {
			"name": "Artem"
		},
		"as_boolean": true,
		"as_color": "#ffffff"
	},
	"id": "test.data"
}

TIP

По умолчанию, конфигурация (config.scss) каждого компонента экспортируется автоматически в exports/sass-options.json файл с помощью следующего "виртуального" метода:

@use "ungic.components.test" as test;
$export: test.export('config', test.config());
...
// И так для каждого компонента.

# Конфигурация компонента (config.scss)

Опциональное присутствие.

Опциональный конфигурационный файл компонента. Данный файл может содержать в себе любые конфигурационные параметры необходимые для стилизации компонента. Для получения параметров указанных в config.scss файле используется config метод ядра компонента:

@use ".core" as this;
@debug this.config(); // Получить все конфиг. параметры
@debug this.config(param); // Конкретный параметр

Конфигурация каждого компонента автоматически экспортируется в JSON формате.

TIP

Конфигурация компонента может быть переопределена из проекта в config-over.scss файле!

Обратите внимание!

При работе с цветом в конфигурационном файле, следует избегать использование произвольных цветов (иначе темизация данного компонента будет невозможна). Для этого, следует использовать ungic.theme модуль:

// config.scss

@use "ungic.theme" as theme;
$color-of-component: theme.color(text-color);

# Стилизация компонента (properties.scss)

Опциональное присутствие.

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

# Пользовательский тип (mixins / functions)

Опциональное присутствие.

Компонент, может иметь любое кол-во файлов и директорий которые могут служить модулями и состоять из функций, миксинов и прочего. Для того, чтобы подобные модули компонента были доступны другим компонентам их следует "продвигать" с помощью @forward (opens new window) директивы в index.scss файле компонента.

# Компонент как модуль

Любой компонент можно использовать в роли SASS модуля и включать в другие компоненты с помощью @use директивы. При использовании компонента в роли модуля, мы получаем доступ как к ядру компонента, так и к пользовательским сущностям (функциям, миксинам, переменным и даже к CSS правилам!):

// Использование компонента grid
@use "ungic.components.grid" as grid;

// Доступ к конфигурации компонента
@debug grid.config(columns-counts); // 12

// Пользовательские функции / миксины
@include grid.media(screen "and" grid.media(max-xs)) {
    .test {
        display: none
    }
}

// Результат
@media screen and (max-width:596px) {
    .test {
        display: none
    }
}

TIP

Для того, чтобы можно было получить доступ к пользовательским методам компонента, следует "продвинуть" их с помощью @forward директивы в index.scss фале компонента:

@forward ".core";
@forward "functions";
@forward "mixins";

Также, можно включать конкретную часть компонента:

@use "ungic.components.grid.functions" as *;
@use "ungic.components.grid.mixins" as *;

Обратите внимание!

Можно включить любой файл или директорию (с index.scss файлом) компонента. Для этого, следует указать полный путь до файла используя . точку для разделителя сегментов пути. В случае включения .scss файла, расширение не указывается!

Обратите внимание!

В случае включения части компонента, имена директорий или файлов не должны содержать символ точки .

Ссылки по теме: