Архівний матеріал: розбір публікації від 2022-01-03. Назви функцій, інтерфейс, можливості плагінів і умови доступу наведені в контексті того часу.
У статті розглядається підхід, який авторка Aleksandra Nagornaia застосувала в продуктовій команді: замість нескінченного розмноження варіантів компонентів у Figma команда перейшла до композиційної моделі з контейнерами та вмістом. На прикладі звичайного, але дуже варіативного елемента списку показано, як це зменшує кількість варіантів, стабілізує стани та зближує дизайн з кодом (SwiftUI, Jetpack Compose).
Проблема: варіанти вибухають, стани роз'їжджають
Великий продукт, спільна дизайн-система, кілька платформ (iOS, Android) і звична ситуація: команда витрачає години на одні й ті самі дискусії.
- Чи це окремий компонент чи ще один variant?
- Які властивості віддати в конфігурацію, а що зашити жорстко?
- Як поєднати різні стани й модифікатори в одній структурі?
Особливо болісним елементом став list item. У продукті було багато його варіацій:
- Title-Subtitle з правим chevron
- той самий, але замість chevron — іконка info
- з аватаркою або зображенням зліва
- із switch, чекмарком, додатковим текстом справа тощо
Усі вони при цьому ділили однакові стейти: selected, pressed, disabled, різні типи background (primary, secondary, accent).
Початковий підхід був класичним для Figma: зробити колекцію всіх можливих list item як окремих компонентів та їхніх варіантів, названих «List item 1» ... «List item 8». Кожен мав свій фон, паддінги й конфігурацію вмісту.
Наслідки в реальних макетах:
- Несумісні стани
- в одному файлі choice-list показував вибір через затінений фон,
- в іншому — лише через чекмарк праворуч.
- Різні відступи
- паддінги list item відрізнялися між екранами, хоча мали бути єдиними.
Як тільки потрібно було змінити, наприклад, secondary background або типографіку Title, виникав масштаб роботи: 32 варіанти компонентів, у кожному треба поправити кут радіуса, шрифт чи відстані. Це прямий шлях до розсинхрону між екранами й платформами.
Варіації проти композиції: чому «тільки variants» не тягнуть
Підхід variation: усі стани всередині кожного компоненту
Спочатку команда пішла шляхом, який часто рекомендують у контексті Figma Variants:
- Зібрати всі типи list item, які реально зустрічаються в інтерфейсі (із іконкою, без, з Subtitle, зі switch тощо).
- Для кожного такого типу додати стани як variants: secondary, accent, pressed, selected тощо.
Формула проста: якщо One-sided list item має 3 базових варіанти, а для кожного передбачено 2 додаткові стани, то загалом виходить 3 × (1 + 2) = 9 variants. Для набору з кількох видів list item це швидко перетворюється на десятки варіантів.
Проблеми цього підходу:
- Дублювання фону та стейтів: однакова логіка background повторюється в кожному компоненті.
- Складність підтримки: будь-яка зміна фону, типографіки чи відступів вимагає правок у кожному варіанті.
- Зростання кількості помилок: щось десь забули змінити, один стейт відстав від інших — з'являються «нові» неузгоджені патерни в макетах.
На цьому місці команда відмовилась від чистого variation і перейшла до composition.
Композиційний підхід: контейнери, контент, підсилюючі елементи
Авторка відштовхується від розуміння, як сучасні UI-фреймворки працюють із компонентами: SwiftUI для iOS та Jetpack Compose для Android будують UI як композицію дрібніших елементів. Figma з Auto layout, Variants та Component properties вже дозволяє відзеркалити цей підхід.
Базова ідея: відокремити оформлення та поведінку оболонки від конкретного вмісту. Для list item вводяться три типи будівельних блоків.
1. Container-background: фон і паддінги як окремий компонент
Перший шар — це контейнер, який описує лише:
- background (колір, кут радіуса, тіні)
- паддінги та базове позиціонування вмісту.
Усередині цього контейнера лежить Generic content placeholder — інстанс, який потім можна поміняти на будь-який інший компонент.

Стейти primary, secondary, accent, pressed, selected переносяться саме в ці Container-background компоненти. Вони більше не дублюються в кожному виді list item.
2. Enhancing-elements containers: чекмарки, chevron, switch
Другий шар — контейнери підсилюючих елементів. Це компоненти, які:
- розміщують сталий елемент (chevron, switch, чекмарк, кнопку, іконку) у певному місці (праворуч, з певними відступами)
- знову ж таки містять усередині той самий placeholder для контенту.

Важливий момент: ці Enhancing-elements containers не мають власного фону та паддінгів як таких — вони «успадковують» це від Container-background, у який будуть вкладені. Завдяки цьому один і той самий контейнер зі switch може працювати поверх будь-якого фону.
3. Content: власне вміст компоненту
Третій шар — контент без фону. Наприклад, Multiline list item: заголовок, підзаголовок, ймовірно, іконка або аватар.

Ці компоненти описують тільки структуру вмісту: текстові стилі, вирівнювання, поведінку при багаторядковості. Вони не знають нічого про стани фону чи наявність правого елемента.
Як це збирається разом: мислення по Z-осі
Щоб отримати фінальний list item, команда рухається «знизу вгору» — по Z-осі:
- Взяти потрібний Container-background зі стейтом (наприклад, Secondary — pressed).
- Усередині нього замінити placeholder на визначений Content (наприклад, Multiline list item).
- Якщо потрібен підсилюючий елемент (switch, chevron, чекмарк):
- спочатку замінити placeholder на Enhancing-elements container (наприклад, контейнер зі switch справа),
- а вже всередині нього підмінити внутрішній placeholder на Content.
У підсумку вийде list item, який:
- успадковує усі стани та стилі фону з одного місця
- використовує універсальний правий елемент (switch/chevron/иконка) як композиційну «надбудову»
- може містити будь-який контентний компонент всередині.
Такий підхід майже 1 в 1 відображає код на SwiftUI чи Jetpack Compose, де окремо описуються модифікатори контейнера (background, padding) і окремо — вміст.

Чим композиція корисна: 5 практичних ефектів
1. Консистентність фонів і стейтів
Усі патерни background (primary, secondary, accent, selected тощо) тепер живуть в одному місці — в наборі Container-background. Якщо потрібно змінити колір secondary або радіус кутів, достатньо оновити лише ці компоненти. Усі list item, карти й інші елементи, що їх використовують, автоматично підхоплять зміни.
2. Менше простору для помилок у макетах
Коли дизайнери використовують підготовлені контейнери, стає набагато складніше «вигадати» свій варіант відступів або підсвічування. Компонент уже визначає:
- де лежить контент,
- як поводиться фон у різних стейтах,
- що таке «правильні» paddings.
Помилки типу «тут інший відступ» або «вибраний елемент підсвічено іншим чином» зникають, якщо тільки хтось свідомо не від'єднає інстанс компонента.

3. Гнучкість без втрати єдності
Композиція дозволяє вкладати всередину list item майже будь-який контент: інший компонент, складну групу, комбінований блок. При цьому фонові стейти та поведінка залишаються уніфікованими.
У звичайній моделі часто треба або:
- розширювати компонент новими варіантами (й не встигати за всіма кейсами),
- або збирати нові компоненти «з нуля», втрачаючи консистентність.
У композиційному підході контейнери працюють як «гнізда», куди можна посадити різний вміст, не змінюючи самі патерни контейнерів.
4. Радикальне скорочення кількості variants
list item більше не мають у собі дубльованих state-варіантів фону та правих елементів. Стани винесено в Container-background, а підсилюючі елементи — в окремі Enhancing-elements containers.

Якщо поширити це на весь дизайн-систем, стає помітно, наскільки варіантний підхід погано масштабується, коли мова йде про десятки компонентів, що ділять однакові фонові патерни та UI-елементи.
5. Єдина мова для дизайнерів і розробників
Коли структура компонента в Figma повторює структуру в SwiftUI чи Jetpack Compose, спрощуються:
- handoff і специфікації — не потрібно вигадувати додатковий шар опису,
- обговорення — і дизайнери, і розробники говорять про ті самі «контейнери», «контент» і «enhancing elements».
Авторка зазначає, що цей же композиційний підхід команда поширила на:
- cards — повторне використання фонів «active», «highlighted», «disabled»
- bottom sheets — уніфікований контейнер, усередині якого змінюється вміст.

Коли композиція доречна, а коли — ні
Авторка формулює загальне правило: варто переходити до композиційної структури, якщо компонент можна розумно розрізати на дві частини:
- Generic content — зона, що може прийняти будь-який UI-вміст (текст, іконки, складні блоки).
- Enhancing elements — сталі UI-елементи та поведінка: фони, чекмарки, switch, анімації, які «підсилюють» контент.

Цей критерій залишає простір для інтерпретації — різні члени команди можуть по-різному бачити, де проходить межа між контентом та підсилюючими елементами. Утім, це скоріше плюс: одна й та сама ідея дозволяє побудувати кілька валідних архітектур.
Водночас є кейси, де композиційний підхід створює зайву складність. Наприклад, текстове поле, фон якого безпосередньо реагує на стан вводу (фокус, помилка, успішний ввід).

У такому випадку між content (input) і фоном виникає сильне зчеплення: вони не є «агностичними» один до одного. Виносити фон у загальний контейнер може бути недоцільно — простіше тримати його всередині самого компонента поля вводу.
Як організувати ієрархію компонентів у Figma
Якщо вирішуєте переходити на композиційний підхід у дизайн-системі, авторка радить розділити компоненти за трьома рівнями:
- Container-backgrounds
- компонуються по Z-осі, утворюючи «шари фону»
- містять лише стилі: background, corner radius, shadow
- задують загальну схему layout: паддінги, положення зони контенту.
- Enhancing-elements containers
- контейнери з додатковими елементами (chevron, switch, кнопка, іконка)
- мають власну логіку розміщення підсилюючого елемента відносно контенту.
- Content
- компоненти з «чистим» контентом: текст, іконки, форматування
- є кінцевими вузлами дерева композиції — далі вже немає абстракції placeholder.

У такій системі компоненти працюють як «lego»: у теорії можна скласти дуже багато комбінацій, частина з яких у реальному продукті не знадобиться або навіть буде нелогічною.

Як обмежити «надлишкові» комбінації
Повна свобода композиції означає, що формально можна скласти, наприклад, list item з одночасно чекмарком і switch праворуч — хоча в інтерфейсі це не має сенсу. Щоб не покладатися лише на дисципліну дизайнерів, авторка пропонує частково «зашивати» обмеження в самих компонентах.
Приклад — Navigation list item:
- береться Container-background з двома станами (default, pressed)
- поєднується з Enhancing-elements container з chevron
- цей «зв'язаний» набір оформлюється як окремий компонент Navigation list item.
Тепер усередину можна підставляти будь-який контент, але:
- не можна тонко змінити стейти фону (наприклад, додати «highlighted», який у цьому патерні не передбачено),
- не можна раптом додати ще один підсилюючий елемент (switch чи чекмарк) поверх chevron.

За тим самим принципом можна задати Switch list item, Selectable list item та інші типи, кожен з яких фіксує допустимі поєднання контейнерів та елементів.
Що в підсумку отримала команда
За описом авторки, команда застосувала композиційні компоненти для cards і list items на iOS та Android і залишилася задоволеною результатом. Компонентобудування стало складнішим на старті, але:
- підтримка виявилася дешевшою — менше ручних оновлень, коли змінюється фон або логіка стейтів
- розробникам стало простіше віддзеркалювати дизайн у SwiftUI/Jetpack Compose
- дизайнери рідше «ламають» патерни, бо ключові рішення зафіксовано в контейнерах.
Авторка окремо підкреслює: навіть якщо такий підхід поки не впроваджено в коді, уже лише на рівні Figma він дає відчутну вигоду — зменшує кількість variants і час на обслуговування дизайн-системи.
Детальніше про суміжні теми можна прочитати у матеріалах Smashing Magazine, на які посилається стаття, зокрема про handoff з Figma в код: https://www.smashingmagazine.com/2023/11/design-to-code-handoff-process-uno-platform-figma/ та про роботу розробників у Figma: https://www.smashingmagazine.com/2022/08/everything-developers-must-know-about-figma/.
Джерело: Aleksandra Nagornaia – Smashing Magazine. Дата оригіналу: 2022-01-03.