Разумное переопределение в наноостровах
Opened this issue · 12 comments
Пролог
Сейчас в наноостровах каждый контрол является в некотором смысле монолитным, так что пользовать им нужно через АПИ. Со временем, требования к контролам растет — растет АПИ.
Кажется, что в некоторых случаях, этого можно избежать, введя возможность переопределения в заранее размеченных, предусмотренных местах.
Задача
Есть кастомная проектная иконка, которую не хочется или не получается вынести в острова.
В таком случая, можно сделать такую иконку просто прокинув кастомный класс.
Есть кнопка, вдруг в этой кнопке появляется кастомная иконка.
Кажется, в этом месте было бы удобно ввести место для переопределение. Поясню на примере:
Сейчас шаблон для кнопки выглядит так:
match .button nb {
<button>
_nb-button-attributes('button')
_nb-button-static()
apply . nb-main-attrs
<span class="_nb-button-content">
if .icon {
nb-icon({
'icon': .icon
})
}
_nb-button-content()
</span>
</button>
}
Может выглядеть так:
match .button nb {
<button>
_nb-button-attributes('button')
_nb-button-static()
apply . nb-main-attrs
<span class="_nb-button-content">
apply .[.icon] nb-button-icon
_nb-button-content()
</span>
</button>
}
match .button nb-button-icon {
nb-icon({
'icon': .icon
})
}
тогда на проекте можно написать:
...
// где-то в шаблоне кнопка
nb-button({
'icon': 'custom-icon'
})
...
// элегантно подхачиваемся к шаблону блока
match .button[.icon == 'custom-icon'] nb-button-icon {
// здесь моя кастомная иконка
}
Кажется, что это выглядит хорошо. Можно заранее разметить блоки так, чтобы давать возможность для разумного переопределения, в тех местах, где это действительно может понадобиться.
В открытое АПИ в таком случае должны быть включены названия мод шаблонов.
Так же, кажется, это может быть удобно, когда в самой библиотеке станет большей уровней переопределение, чем ноль — появится мобильная версия блоков.
Тогда будет:
|--- button
|--- | --- button.desktop.yate
|--- | --- button.mobile.yate
первый содержит шаблоны по умолчанию, а во втором файлике — переопределения с предикатами .isMobile
, так что можно переопределить ту же иконку, например.
Таким же образом можно решить следующую задачу с кастомной иконкой.
Сейчас пишем так:
nb-icon({
'icon': 'custom'
'class': 'nb-icon_custom nb-icon_size_m'
})
В итоге получаем странный класс nb-s-custom-icon
, которого нет нигде. Да и использование class
таким образом — явный хак.
Можно было бы написать так:
...
nb-icon({
'icon': 'custom'
})
...
match .icon[.icon == "custom"] nb-icon-classes {
'nb-icon_custom nb-icon_size_m'
}
Мне нравится пример с иконкой и не нравится пример с классом. Мне кажется, переопределение нужно использовать в тех случаях, когда нельзя удобно сделать это через json-api. Т.е. мне кажется правильным использовать переопределение через yate-api только для элементов составного блока.
Действительно, пример с классом надуманный получился: через параметры блока короче.
Я бы не хотел давать точки для переопределения.
Это потеря контроля над содержимым блоков.
Сейчас разработчики вынуждены делать все через АПИ.
Внимание вопрос, зачем тебе
// элегантно подхачиваемся к шаблону блока
match .button[.icon == 'custom-icon'] nb-button-icon {
// здесь моя кастомная иконка
}
для чего конкретно, и есть ли то что ты хочешь в гайдах?
Другими словами я готов к таким вещим в сложных составных блоках типа шапки и домика, но никак не в кнопке.
Я в очередной раз напишу: гайды — не цель, а направляющие, в них не должно быть всё-всё-всё, они должны служить базой. Хорошие гайды не появляются на пустом месте, а растут вместе с дизайном и с сервисами, их использующими. Невозможно в гайдах вывести все возможные сценарии использования блоков и элементов. Поэтому и нужны различные точки переопределения.
Я не считаю, что фреймворк должен сковывать оковами и не давать ничего переопределять. Я не понимаю, зачем нужен такой жёсткий контроль.
Любые проблемы, которые у разработчиков могут появиться при обновлении фреймворка будут регламентированы семвером, и это будет проблема разработчиков.
Но если фреймворк не будет предоставлять своим пользователем достаточных возможностей переопределения, разработчики начнут всё делать хаками или с ноля, и, в итоге, просто уйдут от использования фреймворка. Есть такая вот опасность.
@basvasilich есть конретный пример кастомных иконок в кнопках.
Представим, что у меня есть 100500 кнопок с кастомной иконкой. Сейчас я могу либо отказаться от возможность вставлять иконку в кнопку через соответствующее АПИ и писать везде через поле content
nb-button({
'content': apply . my-custom-icon-with-title
})
match / my-custom-icon-with-title {
nb-icon({
'icon': 'my-custom-icon'
})
' Нажать!'
}
или я мог бы по всему проекта спокойно писать:
nb-button({
'icon': 'my-custom-icon'
'content': 'Нажать!'
})
и один раз написать свое проектное доопределение:
match .button[.icon == 'my-custom-icon'] nb-button-icon {
nb-icon({
'icon': 'my-custom-icon'
})
}
По-моему, очевидно, что последний путь — верный. Разве, нет?
Конечно, можно обойтись и другими путями, но выглядит как хаки.
Кажется, все согласились с тем, что переопределение допустимо только в составных блоках. Вопрос теперь только в том, является ли кнопка с иконкой составным блоком?