Як я переношу систему дизайну Klad із Figma до Storybook

💡 Усі статті, обговорення, новини про AI — в одному місці. Приєднуйтесь до AI спільноти!

Як за допомогою AI-агентів перетворити хаотичний набір елементів інтерфейсу на функціональний Storybook, не з’їдаючись від обмежень та помилок

Як все почалося

У Klad був набір елементів інтерфейсу. Ну, технічно він був.

Насправді це була просто збірка примітивів і компонентів без будь-якої документації. Довгий час я працював над Klad паралельно з іншими проєктами, і головним пріоритетом було якнайшвидше випустити нову функцію чи оновлення. Не вистачало часу, щоб усе як слід упорядкувати. Ось чому в компонентах можна було побачити такі позначення, як «grey/50». Коротше кажучи, там панував невеликий безлад (не судіть занадто суворо 😁).

Все це працює до певного моменту. Потім стає зрозуміло, що ситуація тільки погіршуватиметься. Ось чому зараз я перетворюю все на примітиви, семантику та компоненти.

Перша проблема, на якій я застряг

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

Він має описувати реальну модель використання. Якщо я не бачу чіткої картини того, як він використовується, я не створюю семантику — я просто вигадую її.

Робити це вручну — довго, а екранів там понад сотню. Я навіть не намагався використовувати офіційний Figma MCP з такою кількістю запитів.

Тож вирішив спробувати плагін Code Runner для Figma. І він упорався. Хоча в процесі я був майже впевнений, що він завис, бо той просто мовчав 2–3 хвилини. Спочатку я прогнав його по іконках, які вже були в UI kit, щоб він точно знав, що шукати далі. Без цього кроку він сканує весь файл і нічого не знаходить.

Потім, для зручності, я створив окремий скіл для Code Runner, щоб не доводилося щоразу вручну вставляти скрипт. До того ж я вже одночасно користувався Figma Desktop Bridge та Figmosha.

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

Два воркфлоу, які я протестував

Частина 1: Від кольорів до компонентів

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

Що стало зрозуміло:

  • Це довгий шлях, а на Pro-плані ліміти закінчуються швидше, ніж робота
  • Клод потрібен мені й для інших задач, а не тільки для дизайн-системи
  • Поки цей процес не завершено, у мене немає жодного готового компонента, який можна було б просто взяти й використати

Другий: за частотою використання компонентів

Тож я змінив підхід. Замість того, щоб пробиратися знизу вгору через усю систему, я беру компонент, дивлюся в аудит використання, скільки його реальних інстансів є у файлі, і починаю з найпопулярніших, або з тих, які потрібні мені просто зараз під конкретну задачу. Решту дозаповнюю паралельно.

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

Різниця у відчуттях приблизно така:

  • У першому воркфлоу: усе впирається в ліміти тарифного плану; я довго будую фундамент і не маю з чим працювати.
  • У другому: досить швидко з’являється невеликий набір компонентів, яким можна довіряти, і він постійно зростає.

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

Хто за що відповідає

Я розділив роботу між агентами так, щоб у кожного була одна чітка задача, а не все підряд у хаотичному порядку.

  • design-system: аудитор і хранитель стану файлу Figma. Він проходить по кожному компоненту: аудит використання → мапінг токенів (Primitive → Semantic → Component, з обов’язковою перевіркою на наявність семантичного аліасу перед тим як залишати мапінг на примітиві) → заповнення відсутніх станів → генерація блоку Spec прямо у Figma. Цей же агент веде документацію: PRODUCT.md, DESIGN.md, а також глосарії токенів та компонентів.
  • storybook: підключається після того, як компонент фіналізовано у Figma (опрацьовано стани, прив’язано токени). Синхронізує його зі Storybook: метадані реєстру → білд токенів (DTCG → Style Dictionary) → сторіз та MDX.
  • frontend-dev: розробник, а не дизайнер. Бере конкретний фрейм Figma і відтворює його в коді точно так, як показано: HTML/CSS на основі токенів, ніколи у вигляді растрового зображення. Використовується тоді, коли є чітке джерело у Figma для копіювання.
  • prototype: навпаки, дизайнер. Будує новий екран з нуля, без конкретного фрейму Figma у якості джерела, спираючись на вже валідовані компоненти з дизайн-системи.
  • figma-builder: використовується тоді, коли щось нове потрібно побудувати прямо у Figma (новий екран, модальне вікно) методом «продублювати → змінити», а не в коді.
  • figma-review: окремий контролер, а не будівельник. Детальніше про нього нижче, оскільки спочатку його не було в плані.

Покроковий флоу

Фаза 1: Аудит та дизайн компонента у Figma

Компонент не просувається далі, доки не пройде чотири кроки:

  1. Аудит використання: скільки реальних інстансів існує і де саме вони використовуються. Я витягую дані через Figma Desktop Bridge та Figmosha, а коли потрібна швидка перевірка, використовую Code Runner, оскільки це економить токени. На основі цього генерується опис, тобто з даних, а не з пам’яті. Водночас відбувається резолюція прив’язки токенів: для кожної прив’язки кольору та тексту система перевіряє, чи варто замінити прив’язку Primitive на існуючий семантичний (шляхом звірення з таблицею в DESIGN.md). Будь-які баги, що спливли під час аудиту, виправляються одразу ж (спрацьовує не завжди тут потрібен контроль).
  2. Заповнення відсутніх варіацій станів, якщо чогось бракує.
  3. Генерація сторінки компонента прямо у Figma: панель специфікацій плюс сітка станів. Стовпці адаптуються під тип компонента: якщо є різні ComponentSets, стовпці представляють варіації типів; якщо є єдиний ComponentSet із кількома властивостями, стовпці представляють змістовні комбінації.

4.Оновлення файла задачі та Дашборду.

Водночас дизайн-система синхронізує файли (DESIGN.md, PRODUCT.md, TOKEN-CONCEPTS.md, COMPONENT-CONCEPTS.md). Це єдине джерело правди для всіх наступних агентів, тому воно не повинно відставати.

Крок 2: Міграція в Storybook

Це спрацьовує тоді, коли в Задачах з’являється компонент зі статусом «завершено» — це означає, що аналіз використання, $description, стани та прив’язка токенів уже готові.

  • Запис у ds/registry/components.json — єдине джерело метаданих (стани, токени, анатомія, варіанти, зв’язки/підказки AI)
  • stories/components/{Name}.stories.js — HTML-рендеринг на основі CSS-змінних, плюс матриця AllStates
  • {Name}.mdx — імпортує дані з реєстру (ніколи не зашивається жорстко в код), плюс Swift-сніпет для iOS
  • Якщо є нові токени: DTCG JSON → запуск npm run build із папки ds/, що генерує CSS та Swift, і це автоматично підтягується в Storybook через Vite HMR

Обов’язковий чеклист перед закриттям:

  • доступність (a11y): фокусне кільце, клавіатура, контрастність, тач-таргет від 44px
  • Звіт про використання токенів
  • бейдж: ready → stable, tokens-ready → beta, in-progress → alpha

Останній пункт виявився важливішим, ніж я думав. Без чіткого «бейджа» я міг невимушено додати в прототип ті компоненти, які насправді ще не були готові.

Крок 3: Незалежний етап перевірки (Review Gate)

Якщо потрібно відтворити конкретний фрейм з Figma (у Storybook чи в прототипі), він не вважається завершеним, доки його не перевірить окремий рев’юер.

Що робить Figma-рев’юер:

  • Він самостійно витягує дані з Figma з нуля. Він не використовує значення з поточного чату з білдером; це фундаментальний принцип
  • Перевіряє структурну повноту: дерево вузлів Figma (кожен видимий дочірній елемент, інстанс, стан) порівнюється з кожним елементом у коді рендеру. Будь-яка розбіжність, навіть найменша (бейдж, тінь, іконка), помічається та фіксується
  • Перевіряє точність значень (колір, відступи, радіус, тінь, шрифт) за живими даними, а не «на око»
  • Порівнює скріншот вузла з Figma зі скріншотом рендеру через живий сервер (а не через file://) і проводить порівняння пліч-о-пліч
  • Перевіряє, чи кожен елемент мапиться на існуючий запис у реєстрі. Якщо ні, він не вигадує назву, а записує статус «ПОТРЕБУЄ-УТОЧНЕННЯ» з конкретним запитанням
  • Записує результати у файл Задач у двох блоках: «ПІДТВЕРДЖЕНО-ВИПРАВИТИ» з конкретним джерелом та «ПОТРЕБУЄ-УТОЧНЕННЯ» із запитаннями до мене

Крок 4: Використання в прототипах

Тут відмінність полягає в намірі, а не в інструменті.

  • Є конкретний фрейм у Figma для точного відтворення → frontend-розробка, підхід code-first, UI-компоненти ніколи не є растровими зображеннями (так так про це написав, тому що був витягнув таби як зображення, а не як компонент😁).
  • Новий екран будується з нуля, без джерела у Figma, із використанням вже затверджених компонентів дизайн-системи → прототип, флоу дизайну: shape (формування) → build (збірка) → critique/polish (критика/полірування). Тут перевірочний етап (gate) не потрібен, оскільки немає чого верифікувати

І саме тут вступає в гру той вибір із самого початку. Поки Етапи 1–3 доводять один компонент до стану «ready», інші вже можуть використовуватися в прототипах через реєстр Storybook, а решта паралельно доповнюється агентом дизайн-системи.

Коли воркфлоу налаштовано, але помилка все одно виникає

Все описане вище виглядає як налагоджений механізм. Тому я виділю конкретний випадок, коли це не спрацювало.

Це сталося не на самому початку, коли ще нічого не було налаштовано. Воркфлоу вже було створено, а чотири кроки Етапу 1 уже знаходилися у файлі агента. І все ж це не спрацювало.

Завдання також було сформульовано правильно: документація для компонента Card Save за стандартним воркфлоу. Проблема виникла на боці головного агента, а саме в тому, як він делегував завдання.

Перед призначенням завдання агенту він прочитав лише конвенції блоку Spec із навички, а не сам файл агента, де описані ці кроки. У результаті промпт вийшов вузьким — по суті, зосередженим на третьому кроці: створити блок Spec. Агент зробив саме те, про що попросив головний користувач. Він не виправив прогалини в токенах, а акуратно задокументував їх як «відомі прогалини» в плашці статусу.

Поруч із цим виникла друга проблема, яка виявилася непов’язаною. У Card Save текстовий шар був прив’язаний напряму до примітива color/Neutral/90, хоча семантичний колір color/text/default із тим самим значенням уже існував у DESIGN.md. Причина полягала в тому, що правило «перевіряти DESIGN.md на наявність існуючих семантичних аліасів перед прив’язкою» існувало лише в приватній пам’яті асистента. Інша сесія, яка виконувала прив’язку через Desktop Bridge, просто не мала доступу до цього правила.

Обидва висновки тепер збережені у файлах, а не в пам’яті: читати весь файл .md агента, а не лише навичку, та впровадити tier-check як методологію у WORKFLOW.md і в самому файлі агента. Тому що субагенти не читають нічию приватну пам’ять.

Але для мене головним було не це. Наявність воркфлоу нічого не гарантує, якщо промпт звужує завдання до одного кроку. Агент не скаже вам, що ви пропустили початок. Він просто виконає завдання і поверне результат, який виглядає завершеним. Саме тому ви повинні перевіряти це самі — і зосереджуватися саме на цих дрібних деталях, а не лише на тому, чи блок Spec на своєму місці.

Задачі як центр управління та фіксації рішень

Кожен компонент чи екран — це окремий файл у директорії Tasks/ із назвою на кшталт 2026-07-24-comments-reviews.md. Угорі розміщено YAML-заголовок: статус, дати, призначений агент та контекст (A — Figma, B — прототип, C — Storybook).

Що туди входить. Не результат, а рішення. Конкретні ID вузлів із Figma, які потрібно віддзеркалити. Зафіксовані рішення — тобто те, що вже узгоджено і не підлягає перегляду. Точні значення, витягнуті з живого пулу: не «приблизно сірий», а #ededed, радіус 12, розмір 336×108. Чеклист за фазами. Вердикт перевірочного етапу (gate). І окремо — припущення, які агент зробив самостійно і які я маю підтвердити або спростувати.

Останній пункт виявився важливішим за інші. Коли агент чогось не знає, йому заборонено просто вгадувати. Він записує це в задачу як запитання. Більше того, це правило розширилося далі: якщо перевірочний етап знаходить елемент, який не мапиться на жоден відомий компонент, агенту Storybook заборонено створювати для нього запис у реєстрі, доки я не підтверджу, чим він є насправді. Невідомий патерн не стає фактом у документації сам по собі.

Правило напрямку: Tasks → registry, і ніколи навпаки. Агент Storybook бере дані із задачі й поміщає їх у ds/registry/components.json. Зворотного процесу, коли документація пишеться з нуля, а задача потім підганяється під неї, не існує.

Завдяки цьому задача фактично є визначенням готовності (definition of readiness). Агент Storybook запускається лише тоді, коли задача має статус «завершено» і містить чотири елементи: аналіз використання, $description, стани та прив’язку токенів. Якщо хоча б одного з них бракує, компонент не рухається далі, навіть якщо візуально він виглядає готовим.

Як аудит використання змінює опис компонента. Button Primary Black, Size=lg: 348 інстансів на 5 сторінках, 211 з яких знаходяться в контексті «Колекція» всередині карток. Це не той компонент, яким я його уявляв до аудиту. Після цього $description пишеться на основі цифр, а не намірів.

Завдання з прототипування формує беклог для дизайн-системи. У таблиці компонентів для кожної такої задачі є маркер «flag DS» — він позначає те, що наразі існує лише як CSS у прототипі, але ще не як багаторазовий компонент у Figma. Останнє завдання (Comments & Reviews) дало сім таких кандидатів: вибір реакцій, картка відгуку, картка гілки коментарів, чіпси фільтрів, таб-бар, блок статистики та кнопка «Залишити відгук».

Я свідомо не почав одразу переносити їх у компоненти. Але вони зафіксовані з посиланнями на конкретні вузли. Різниця між «я це пам’ятаю» та «це є у файлі» — це різниця між порядком і хаосом.

Завдання можна відкрити повторно. Primary Button було закрито в червні. У липні виправлення токена для зовсім іншої кнопки (Secondary 3D) торкнулося спільної змінної, і стан Disabled у чорної кнопки тихо став майже білим. Це виявили лише через кілька тижнів. Статус у задачі змінився з «done» до «done-with-open-issue» з описом того, що саме зламалося і чому попереднє значення також було неправильним.

Якби цього файла не існувало, компонент і далі вважався б завершеним 😅

Де я звірявся з готовим рішенням

Свій скіл під Storybook у мене вже був, але коли побачив dobzha-storybook-ds-skill, вирішив звіритись і доповнити свій.

Він зафіксовує Storybook як єдине джерело правди для компонентів, станів та токенів. При запуску він визначає, з чого ви починаєте (з нуля, з існуючого коду, з Figma чи із вже загарбаного Storybook) і проводить вас відповідним сценарієм.

Висновок

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

Що далі?

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

👍ПодобаєтьсяСподобалось6
До обраногоВ обраному2
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Підписатись на коментарі