Разберёмся, как меняли компоненты при достижении определённых значений раньше и как можно это делать сейчас.
Самый старый трюк
Очень давно пользователи Figma заметили одну интересную особенность: при сжатии фрейма сверх 1px он отражается. Вы, скорее всего, знаете об этом. Но знаете ли вы, что этим эффектом можно воспользоваться? Достаточно правильно расставить все необходимые фреймы, чтобы добиться следующего эффекта:
Настройки следующие: все фреймы, кроме родительского, с привязками Left and Right; фрейм Brakepoint 50px расположен за пределами родительского фрейма и изначально имеет размер 50px (а точнее, того брейкпоинта, при достижении которого произойдёт «замена»). Есть и другие возможные реализации этого трюка: фреймы с брейкпоинтами могут располагаться внутри, но смысл остаётся тот же.
На этом принципе работает известный плагин Brakepoints.
Как ни печально, но у этого трюка очень много проблем и ограничений. Например, изменить брейкпоинт можно только вручную и только в мастер-компоненте, никакие трюки типа Resizeable Instance тут не помогут. При этом он указывается относительно изначального размера компонента — сложно и неудобно. Сам компонент достаточно часто ломается и перестаёт работать, а значит, настало время для моей работы!
Охота началась
Я решил попробовать использовать AL Wrap в качестве основы для нового решения. Контент должен заменяться другим контентом, а значит, у нас точно должны быть AL для них. Для бесшовной замены нам необходимо иметь подложку цвета фона, как и в базовом трюке. С контентом от 0 до Breakpoint всё предельно понятно — это обычный AL, а вот контент, который появляется после, придётся накладывать через абсолютное позиционирование и не отображать до достижения брейкпоинта. Ясно, собираем:
Интересен AL Wrap: у него привязки Top, Left и Right, а у Breakpoint Wrapper Min Width = значению брейкпоинта в пикселях и Fill. Null — нулевой фрейм с высотой = высоте заменяемого содержимого.
Так работает, но высота фиксированная и трудно регулируемая, нам такое не подходит. Думаем дальше.
Углубляемся
Следующим решением было изменить подход к «исчезновению» контента: попробуем его вытеснить с помощью заведомо большего компенсатора.
На сей раз Compensator содержит честный нулевой фрейм и Breakpoint — Fill с Max Width = значению брейкпоинта в пикселях, а вертикальный Gap равен большому числу, в моём случае 4000.
Теперь работает намного лучше, да и высота регулируется, но всё ещё не достаточно хорошо: задавать брейкпоинт через значение Max Width не всегда удобно. Постараемся исправить и это.
Финальные штрихи
По результатам экспериментов оказалось, что вместо задания значения Max Width достаточно использовать горизонтальный Gap — результат остаётся тем же. Удобно! Добавим нужные слоты, ещё брейкпоинтов, время делать компонент!
Загадка
Есть способ отображать необходимый контент только в рамках начального и конечного значений (или наоборот). Подсказка: дополнительный компенсатор, работающий от обратного, плюс маска. Удачи!
А пока — достижение.
Пример в фигме доступен по ссылке