Компоненти для споживання, а не для складності: гнучкі та повторювані системи у Figma (частина 1)

Архівний матеріал: розбір публікації від 2023-12-11. Назви функцій, інтерфейс, можливості плагінів і умови доступу наведені в контексті того часу.

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

FRAILS: що насправді хочемо від компонентів

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

  • Flexible — гнучкі,
  • Repeatable — повторювані,
  • Adoptable — ті, що охоче приймають в роботі,
  • Indexable — легко знайдені та впорядковані,
  • Logical — логічно побудовані,
  • Specific — достатньо конкретні.

У першій частині свого матеріалу автор фокусується на двох перших якостях — Flexible та Repeatable. Далі — практичний розбір саме цих двох аспектів, з прив’язкою до Figma.

Гнучкість: коли «можна все» шкодить системі

1. Занадто гнучкі інстанси компонентів

У Figma надто просто створювати нові компоненти й змінювати інстанси існуючих. Команда автора не раз стикалася з тим, що дизайнери дублюють вже наявні компоненти або змінюють інстанси до невпізнанності. З точки зору DRY-підходу (Don’t repeat yourself) це виглядає як анти-патерн.

Типова ситуація: у системі є стан помилки для текстового поля з червоною рамкою. Дизайнер у конкретному макеті змінює рамку на зелену «бо так гарніше для цієї фічі». Формально компонент спрацював як гнучкий, але з точки зору підтримки дизайн системи це руйнує семантику й очікування.

Уріач пропонує дві прості практики, щоб стримати «шкідливу гнучкість» без надмірної жорсткості:

  • Сигналами позначати, що можна редагувати. Наприклад, у назвах шарів та пропертей використовувати емодзі як маркер: де редагувати текст, де змінювати інстанс, а де взагалі не чіпати.
  • Розділяти компоненти за наміром. Замість єдиного універсального Input мати окремі Input/Error, Input/Default тощо. Так дизайнер менше спокушається «перефарбувати» помилку в інший колір — це вже інший семантичний компонент.

Автор показує приклад семантичних позначок емодзі, які команда може узгодити як внутрішній стандарт:

  • Компоненти
    • 🚨 Deprecated — компонент, який не можна більше використовувати,
    • 🟠 Not ready — ще в роботі, не для продакшн-макетів.
  • Інстанси компонентів
    • 🔐️ Not editable — інстанс, який не редагують локально,
    • ✍️ Overwritten name — попередження, що інстансу змінювали назву.
  • Шари
    • ✍️ Editable — шар, який можна змінювати,
    • 🚨 Important — шар, до якого варто ставитись уважно.
  • Component properties
    • ◈ Type — тип компонента,
    • ✍️ Edit text — текстова проперті для редагування,
    • 🔁️ Swap instance — слот для заміни інстанса,
    • 🔘 Toggle — булева опція,
    • ←️ / →️ — напрямки,
    • 🖱 Interaction — налаштування інтеракцій,
    • 📈 Data — прив’язка до даних,
    • ↔️ Size — зміна розміру.

Це не «магічний рецепт», а інструмент швидкої візуальної комунікації: що дозволено, а що ні, прямо в панелі Figma.

2. Гнучкість через responsive-дизайн: де межа Figma

Уріач нагадує класичний принцип responsive web design (RWD): веб за замовчуванням гнучкий, а не фіксований, і це варто прийняти. Але у Figma станом на час написання статті немає «повністю responsive» компонентів у сенсі коду: коли при зміні брейкпоінта автоматично змінюється і напрямок layout, і внутрішня структура.

Технічно можна наблизитись до цього за допомогою auto layout, wrapping та min/max width, але автор застерігає: так легко опинитися у «супі magic numbers» (див. пояснення Кріса Койєра у Magic Numbers in CSS), де набір крихких числових значень важко зрозуміти й підтримувати.

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

  1. Чи команда реально проєктує для різних розмірів екранів (наприклад, мобільний веб і десктоп)?
  2. Чи розробка ведеться під конкретну платформу / діапазон розмірів (наприклад, чисто iOS)?
  3. Чи застосунок будується за нативними гайдлайнами (наприклад, Material Design)?

Комбінації відповідей задають різні стратегії:

  • якщо не працюєте з багатьма брейкпоінтами, але дотримуєтесь нативних гайдлайнів, доцільно розділити Figma-бібліотеки за платформами, щоб, наприклад, iOS-компонент випадково не потрапив у веб-макет;
  • якщо дизайн і код кросплатформені, компоненти можна тримати ближче один до одного, а різницю переносити в тему/реалізацію — автор згадує як ідею Mitosis з підходом «Write components once, run everywhere».

3. Варіанти, секції чи окремі компоненти

Автор описує три поширені способи організації відповідей на питання «цей самий патерн, але для іншого розміру/платформи».

Варіанти з ознакою розміру / платформи

Перший варіант — запхати все в один компонент set і додати проперті типу device або platform. Це може працювати для невеликої системи з відносно простими станами, але зі зростанням кількості state-ів варіант-сет стає важким для використання й підтримки. Для великих команд автор радить скоріше розбивати такі масивні варіанти на окремі компоненти.

Секції за брейкпоінтами

Інший підхід — залишити компоненти відносно простими, а різні брейкпоінти розносити по секціях та сторінках бібліотек:

  1. використовувати окремі сторінки у Figma library для груп компонентів,
  2. на сторінці робити sections по брейкпоінтах (наприклад, Mobile, Tablet, Desktop),
  3. компонентам давати семантичні назви без прив’язки до розміру у самій назві.

Цей варіант добре працює, якщо команді важливо візуально бачити структуру бібліотеки й швидко знаходити потрібний розмір через секції.

Роль auto layout

Незалежно від обраної структури, Уріач підкреслює: auto layout на всіх рівнях — основний інструмент для керованої гнучкості. Правильно налаштований auto layout у компонентах наближає їх поведінку до HTML/CSS, зменшуючи розрив у сприйнятті між дизайном та розробкою.

Але якщо макети для різних брейкпоінтів сильно відрізняються (інша типографіка, інший layout), то, за спостереженням автора, простіше й безпечніше підтримувати кілька компонентів, ніж один «гіпергнучкий», де все зав’язано на умовні значення та змінні.

Повторюваність: як зробити компоненти придатними до багаторазового використання

Будь-який компонент у Figma формально повторюваний: його можна багаторазово вставляти в макети. Але у практиці системного дизайну повторюваність упирається в специфічність контенту всередині компонента:

  • текст (лейбли, заголовки),
  • медіа (зображення, відео, іконки),
  • порядок розташування елементів.

1. Текст: як не зламати overrides

Уріач окремо зупиняється на проблемі «override preservation» — збереження текстових змін в інстансах після оновлення головного компонента.

Класичний сценарій: у базовому input компоненті є текстовий шар з «Label». Дизайнер в інстансі змінює його на «Email address». Пізніше команда вирішує оновити структуру поля, наприклад, винести лейбл над input і створює новий текстовий елемент. Для Figma це вже інший шар, тож мапінг з інстансами втрачається, і всі «Email address» тихо відкотяться до дефолтного тексту.

Щоб знизити ризик подібних втрат, автор радить:

  • максимально використовувати component properties для тексту — додавати текстову проперті до кожного шару, який очікувано змінюється в інстансах,
  • позначати такі проперті, наприклад, емодзі ✍️ в назві, щоб у панелі властивостей їх легко знаходити.

Це не скасовує необхідність обережно переробляти структуру компонентів, але робить поведінку текстових overrides передбачуванішою для всієї дизайн-команди.

2. Наскільки специфічним має бути дефолтний текст

Далі постає питання: яке саме значення має стояти в компоненті «за замовчуванням»?

  • Якщо контент майже завжди змінюють, краще зробити його відверто абстрактним — наприклад, [placeholder]. Це спонукає дизайнера одразу адаптувати текст під свій кейс, а не залишати випадковий дефолтний контент.
  • Якщо ж значення у 90 % випадків однакове, логічно зафіксувати його в самому компоненті («Email address» замість «Label») або навіть створити окремий компонент для таких часто вживаних варіантів.

Автор підкреслює: це продуктове рішення. Команда має орієнтуватися не на «ідеальну абстракцію», а на фактичний або очікуваний патерн використання компонентів.

3. Медіа: бібліотека активів як mini-DAM

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

  • через fill styles,
  • через component sets (variants).

Перш ніж вибирати метод, автор пропонує налаштувати саму структуру медіа:

  • виділити окрему Figma-бібліотеку під медіа; якщо в компанії кілька брендів чи продуктів, то, ймовірно, кілька бібліотек,
  • розкладати медіа з допомогою slash-назв: Домен/Тип/Назва.

Наприклад:

  • Figma.com/Logo/Figma,
  • Figma.com/Icon/Variable,
  • Figma.com/Illustration/Components,
  • Figma.com/Image/Office,
  • Designsystems.com/Logo/Stripe,
  • Designsystems.com/Icon/Hamburger,
  • Designsystems.com/Illustration/Orbs,
  • Designsystems.com/Image/Modular grid.

Так Figma починає працювати як легкий digital asset manager: дизайнер підключає потрібну бібліотеку й працює з бренд-узгодженими активами замість випадкових заглушок.

Fill styles для зображень та відео

Fill styles можна використовувати не лише для кольорів, а й для медіа. Це особливо корисно, якщо:

  • потрібно швидко змінювати набір зображень у межах одного компонента,
  • готові працювати з фіксованими розмірами або пропорціями, щоб уникати хаотичного кропу.

Автор зазначає, що Figma допомагає зберігати пропорції завдяки «snapping» під час ресайзу: червона направляюча показує, коли ви повернулись до оригінального aspect ratio.

Зображення як компоненти з варіантами

Другий підхід — зробити зображення компонентами і використовувати variants для різних фіксованих співвідношень сторін, наприклад 16:9, 4:3, 1:1. Автору цей варіант здається більш керованим у сценаріях:

  • коли дизайн базується на чітко визначеній сітці з відомими пропорціями slot-ів під медіа,
  • коли йдеться про логотипи, ілюстрації, іконки з кількома версіями (filled / outline, різна товщина stroke для різних розмірів).

Уріач ділиться Figma-файлом з прикладом такого підходу — Fixed aspect ratio images with variants.

Важливий акцент: автор не радить силою «робити зображення responsive» у Figma, намагаючись відтворити web-поведінку. Натомість пропонує працювати з обмеженим, заздалегідь визначеним набором розмірів, ближчим до реального фронтенд-оточення, і частіше ставити запитання «чи можемо ми протестувати це в реальному продукті?».

4. Порядок елементів: fixed vs flexible контент

Найскладнішим для повторюваності автор називає порядок елементів всередині компонентів. На прикладі форм він показує типову проблему: системна команда робить «ідеальну» форму як один великий компонент, але в реальних фічах кожній команді потрібна своя комбінація полів, інший порядок, трохи інші підказки.

Це стосується не тільки форм, а й таблиць, меню, списків, навігації. Якщо намагатися весь цей спектр покрити одним-двома компонентами, доводиться або нескінченно множити варіанти, або миритися з локальними «сніжинками» (про які писав Бред Фрост у Design system components, recipes, and snowflakes).

Щоб утримати баланс між DRY і реальною гнучкістю, Уріач пропонує мислити в термінах component slots (аналогія з підходом у Vue: component slots):

  • системна команда постачає контейнер (наприклад, Form/Wrapper) з фіксованими відступами, сіткою, стилями заголовків,
  • усередині контейнера є слот-компонент, який локальна команда може замінити на свій власний компонент з конкретним наповненням (login, registration, billing тощо).

Таким чином, система визначає каркас і правила, а вміст формується ближче до контексту продукту. Автор у відео «Scoped slot components» (посилання: https://www.youtube.com/watch?v=XMqUKlFUETc) демонструє цей підхід у Figma.

Далі постає організаційне питання: де зберігати такі «кастомні» компоненти, створені локальними командами в рамках слота?

  • якщо компонент потрібен у кількох файлах / продуктах, логічно підняти його в спільну бібліотеку (team-level або глобальну),
  • якщо він строго локальний для однієї фічі, автор радить лишати його у файлі цієї фічі, наприклад, на спеціальній сторінці «❖ Components».

Ключова умова для працездатності слотового підходу — той самий принцип: auto layout має бути застосований на всіх рівнях компонента. Без цього контейнер не зможе адекватно реагувати на зміну вмісту слотів.

Що брати в роботу вже зараз

Підхід Луїса Уріяча можна коротко описати так: замість ідеальних «універсальних» компонентів варто будувати системи, в яких:

  • гнучкість не дозволяє ламати семантику (емодзі-позначки, семантичні компоненти замість одного «універсального»),
  • responsive-цілі підпорядковані реальним платформам і брейкпоінтам, а не гонитві за однією «магічною» сутністю,
  • текстові overrides захищені через component properties,
  • медіа організовані як керована бібліотека з чіткою структурою назв і фіксованими пропорціями,
  • складні шаблони (форми, таблиці) будуються через оболонки й слоти, а не нескінченні варіанти одного компонента.

У другій частині свого матеріалу автор переносить акцент на решту частин FRAILS — Adoptable, Indexable, Logical, Specific — тобто як зробити компоненти не тільки гнучкими й повторюваними, а й такими, що їх легко знайти, зрозуміти та прийняти всією організацією.

Ілюстрації з оригіналу

A diagram which illustrates semantic color meanings. Red is for negative, orange is for notice, green is for positive, blue is for informative, and accent recreated from Adobe Spectrum’s design system.
Diagram illustrating through labels the semantic color meanings for red (negative), orange (notice), green (positive), and blue (informative and accent) recreated from Adobe Spectrum’s design system.
On the left is shown a single component, one input that contains two fields (default and error); on the right, there are now two components: one is for default, the other for error.
Splitting components: one input field with a default and error state becomes two individual components.
An illustration that shows emoji naming conventions within components, component instances, layers, and component properties.
Emoji naming conventions within components, component instances, layers, and component properties.
The same card is at different breakpoints: desktop (1440), tablet (768), and mobile (320). The card contains the following elements: a photo of raspberries, ‘Card Title’, ‘Card description’, and ‘Action’ button; and each element within each card is rearranged differently at different breakpoints.
A card at different breakpoints: desktop (1440), tablet (768), and mobile (320).
An image that shows a matrix that can help you decide whether your components should be shared or unique. It is created in the form of a table; the table header has ‘Shared Components’ and ‘Unique Components’; on the left, there is a series of questions in three rows, and there are checkboxes in the columns/rows intersections.
A matrix to help you decide whether your components should be shared or unique.
An illustration that shows a design system structure example within Figma. The title is ‘UI Kit’, and below are five boxes: ‘File: Foundations’, ‘File: Icons’, ‘File: ‘Global’, ‘File: iOS’, and ‘File: Android’.
A design system structure example within Figma.
An example mapping of library files for an iOS design project. The image is similar to the previous one: the title is ‘UI Kit’, and below are five boxes. From the first four boxes (‘File: Foundations’, ‘File: Icons’, ‘File: ‘Global’, ‘File: iOS’), there are four arrows going into another larger box at the bottom that says: ‘File: iOS App designs’. From the box ‘File: Android’, there is no arrow.
An example mapping of library files for an iOS design project.
A screenshot of a page from the Simple design system structure Figma community file, by Luis Ouriach.
The “Simple design system” Figma community file.
A screenshot that shows the use of variants. There are two cards here that are similar to the ones found in the ‘A card at different breakpoints’ illustration. The cards contain the following elements: a photo of raspberries, ‘Card Title’, ‘Card description’, and ‘Action’ button; and each element within each card is rearranged differently for the different platforms: desktop and mobile.
Using variants for different platform types.
An image similar to the previous one in the list. The cards again contain the following elements: a photo of raspberries, ‘Card Title’, ‘Card description’, and an ‘Action’ button. On the left, the Desktop card layout is shown with a horizontal content arrangement, and on the right, the Mobile one with a vertical content arrangement.
Using sections for components.
A screenshot that shows a generic input field, with a value of ‘Label’.
A generic input field.
A screenshot that illustrates an override to the previous input field. The value now reads ‘Email address’.
Let’s change the value of “Label” to “Email address” – this is an override!
A more complex illustration that shows what happens when you make a structural change and the ‘Placeholder’ becomes a ’Label’ above the input field. Top: Old component; bottom: New component.
If you make a structural change and the “Placeholder” becomes a “Label” above the input field, you create a new text element for the label, losing the mapping between your original text element and the new one.
An illustration that shows how a text component property is added to your text layers.
I recommend adding a text component property to your text layers.
Two examples are shown. On the left is ‘Fixed content’, on the right is ‘Flexible content’. In the flexible content example (on the right), a text layer reading ’[placeholder]’ below ‘[Label]’ would prompt a designer to change it to their specific local use case.
Fixed content/Flexible content example. In the flexible content example, a text layer reading “[placeholder]” would likely prompt a designer to change it to their local use case.
There are six boxes in the image. The top row is Media format: [Domain] / [Type] / [Name]; and the bottom row is Media example: Figma.com / Logo / FigJam.
The proposed media format: [Domain] / [Type] / [Name], with an example: Figma.com / Logo / FigJam.
A proposal for a Figma library media structure. Three file boxes on the left: Media → Global, Media → Product, Media → Marketing. Then there’s an arrow that points from these three file boxes to another box on the right, which shows ‘Pages’ at the top of it, and then there are ‘Logos, Icons, Illustrations, Images, Videos’ underneath.
A proposal for a Figma library media structure. There are three files: Media → Global, Media → Product, Media → Marketing. Within these files, the idea is to have the following page structure: Logos, Icons, Illustrations, Images, and Videos.
A screenshot that shows four example styles. Four boxes on it, and inside each box: ‘Figma.com/Logo/Figma,’ ‘Figma.com/Icon/Variable,’ ‘Figma.com/Illustration/Components,’ ‘Figma.com/Image/Office.’
Four example styles: Figma.com/Logo/Figma, Figma.com/Icon/Variable, Figma.com/Illustration/Components, Figma.com/Image/Office.
A detailed image that shows a proposal for structuring a Figma variant component for mixed aspect ratios and sizes. The top shows the X axis (for the aspect ratios), and the left shows the Y axis (for the sizes, in pixels). A photo of a cat is being used to illustrate the different aspect ratios.
A proposal for structuring a Figma variant component for mixed aspect ratios and sizes. Along the X axis are the aspect ratios, and on the Y axis are the sizes.
A detailed image that demonstrates how to nest a main variant component for each image type, which is then nested inside a separate variant component for the size. Again, a photo of a cat is being used in the explanation.
A demonstration of nesting a main variant component for each image type, which is then nested inside a separate variant component for the size.
A detailed image that shows a form component in two variations. On the left, we have a form with ‘full name’, ‘email address’, and a ‘sign up’ button. On the right is shown a form in the same visual style, but the fields are ‘first name’, ‘second name’, and ‘email address’; and the button after the fields is now a button group (two buttons): one button for “cancel”, the other button for “sign up”.
A form component in two variations. Left: We have a form with “full name,” “email address,” and a “sign up” button. Right: Here we have a form in the same visual style, but the fields are “first name,” “second name,” and “email address.” The button has been converted into a button group: one button for “cancel,” the other for “sign up”.
An illustration that shows how to fix the spacing values between each element while making the combinations of components infinitely flexible. Two forms with different spacing component combinations are being shown.
When designing forms, we need to fix the spacing values between each element but make the combinations of components infinitely flexible.
A complex illustration that shows a usage graph for components. There are three main elements in the illustration. The top one shows the ‘Global component,’ the middle one ‘Domain/team component,’ and the bottom one ‘Snowflake component.’
A usage graph for components. If you need a snowflake component specific to your feature work, store it locally in the file. If it is required by your specific team or platform, you can move it into a team library. If it needs to be globally used, move it into the broader design system.


Джерело: Luis Ouriach – Smashing Magazine. Дата оригіналу: 2023-12-11.

Пошук

Закрити