Как организовать файлы в библиотеке компонентов?

Я использую методологию БЭМ, но это общая проблема.

Проблема заключается в связанных модификаторах и блоках.
Объясню что имею ввиду.
У нас есть блок "Кнопка", у нее есть дочерний элемент "Кнопка__иконка" и модификатор "Кнопка--Иконка-Слева"(уменьшает отступ слева, чтоб иконка смотрелась лучше).
59f7249d411cf529105772.jpeg
Если в проекте не нужна иконка в кнопке, нужно удалить модификатор "Кнопка--Иконка-Слева» и элемент "Кнопка__иконка", а также все модификаторы "Кнопка__иконка", если они есть.

Усложним пример. У этой кнопки есть три модификатора размера (sm,m,l). У каждого размера будет разный отступ слева при модификаторе "Кнопка--Иконка-Слева".
59f971253bf61878914072.jpeg
Добавим изменение размера "Кнопка__иконка" для разных размеров кнопки (если это иконочный шрифт можно использовать font-size всей кнопки, но мы как современные используем svg иконки и размер нужно задавать вручную).
Получается такая структура.
59f9713b73caa378176474.jpeg
Это я называю связанные модификаторы.
При такой структуре, мы явно видим что модификатор размера(S,M,L) влияет на модификатор "Кнопка--Иконка-Слева"(Btn--Icon-left) и на элемент "Кнопка__иконка"( Btn__Icon). А значит можно легко найти нужный стиль и изменить его. Плюс, если нам не нужен какой-то из размеров кнопки, удалив одну папку, мы удаляем все его связанные стили. Но есть и обратная сторона, если мы хотим удалить модификатор "Кнопка--Иконка-Слева" и оставить все размеры (S, M, L), то придется заходить в каждую папку размера и удалять этот модификатор.

Теперь о связанных блоках.
В библиотеке есть три блока: "Btn", "Dropdown", "Btn-group".
В "Btn-group" у "Btn" и "Dropdown" убирается скругление углов у всех элементов, кроме первого и последнего по бокам.

.btn-group  > .btn, 
.btn-group > .dropdawn{
border-radius: 0;
}

.btn-group > .btn:first-child,
.btn-group > .dropdawn:first-child,{
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
}
.btn-group > .btn:last-child,
.btn-group > .dropdawn:last-child,{
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
}

59f9724223305896679912.jpeg

Проблема такая же, если в проекты не нужен "Dropdown", то и стили для его скругления в блоке "Btn-group" нам не нужны.

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

В идеале нужна структура, чтоб видеть все связи (пример выше), для быстрого доступа к нужному свойству, но также инструмент, который умеет удалять не нужные стили по связям. Удалив элемент "Кнопка__иконка" в сборку не должны попасть модификаторы "Кнопка--Иконка-Слева" разных размеров.

Может кто то встречался с решением или рекомендациями по данному вопросу.

Спасибо за внимание.
  • Вопрос задан
  • 343 просмотра
Пригласить эксперта
Ответы на вопрос 1
qfox
@qfox
Ответы есть у меня
У нас есть блок "Кнопка", у нее есть дочерний элемент "Кнопка__иконка" и модификатор "Кнопка--Иконка-Слева"(уменьшает отступ слева, чтоб иконка смотрелась лучше).
У этой кнопки есть три модификатора размера (sm,m,l). У каждого размера будет разный отступ слева при модификаторе "Кнопка--Иконка-Слева".


Легко решается через CSS Custom Properties и типографские константы
--sm, --m, --l при этом выставляют эти константы, а другие модификаторы и элементы их используют в нужных им местах.

Добавим изменение размера "Кнопка__иконка" для разных размеров кнопки (если это иконочный шрифт можно использовать font-size всей кнопки, но мы как современные используем svg иконки и размер нужно задавать вручную).


Лучше делать враппер над иконкой, чтобы не завязываться на svg или нет.
Если библиотека компонент общая — ситуации могут быть разные.
Такая структура более менее:
<Button>
  <Button__icon><Icon ... /></Button__icon>
  <Button__body>Текст на кнопке</Button__body>
</Button>


Если иконка есть — выводим `Button__icon`, если нет — не выводим. Стили вешаем на `Button__icon`.

Для кастомизации — оставляем `Button__body`, потом пригодится в кастомных `Select`.

В идеале нужна структура, чтоб видеть все связи (пример выше), для быстрого доступа к нужному свойству, но также инструмент, который умеет удалять не нужные стили по связям. Удалив элемент "Кнопка__иконка" в сборку не должны попасть модификаторы "Кнопка--Иконка-Слева" разных размеров.

Может кто то встречался с решением или рекомендациями по данному вопросу.


Звучит как сборка стилей по зависимостям из bemjson/jsx. Технически, есть возможность даже из html получить bemjson и инициировать для него сборку css/js.
Процесс будет выглядеть примерно так:
const fs = require('fs');
const miss = require('mississippi');
const html2bemjson = require('html2bemjson');
const bemjsonToDecl = require('bemjson-to-decl');
const src = require('gulp-bem-src');
const gconcat = require('gulp-concat');
const vfs = require('vinyl-fs');

src(
    ['path/to/blocks'],
    bemjsonToDecl.convert(
        html2bemjson(
            String(fs.readFileSync('path/to/your.html')))),
    'css',
    { // дополнительные настройки
        skipResolvingDependencies: false, // отключаем зависимости
        {
            'path/to/blocks': { scheme: 'nested' } // у 'path/to/blocks' схема nested 
        }
    }
).pipe(gconcat('path/to/your.css')).pipe(vfs.dest('.'))

Ну и всё
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы