') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); GitHub - ATchernov/FigmaGen · GitHub
Skip to content

Repository files navigation

FigmaGen

Travis CIVersionXcodeSwiftLicense

FigmaGen - инструмент командной строки для генерации кода на основе библиотеки компонентов в Figma.

Поддерживает генерацию:

  • цветовых стилей
  • текстовых стилей

Навигация

Установка

CocoaPods

Для установки FigmaGen с помощью менеджера зависимостей CocoaPods добавьте строку в Podfile

pod'FigmaGen','~> 1.0.0'

Затем выполните команду:

$ pod install --repo-update

В случае установки FigmaGen посредством CocoaPods команда генерации должна включать относительный путь к папке Pods/FigmaGen:

$ Pods/FigmaGen/figmagen generate

Homebrew

Для установки FigmaGen средствами менеджера пакетов Homebrew выполните команду:

$ brew install hhru/tap/FigmaGen

Вручную

Важно: в случае такой установки команда генерации должна включать относительный путь к папке с содержимым ZIP-архива, например:

$ MyFolder/figmagen generate

Использование

Для генерации кода необходимо вызвать команду:

$ figmagen generate

Результатом её выполнения являются файлы исходного кода, согласно конфигурации (см. Конфигурация), которая по умолчанию должна находиться в файле .figmagen.yml.

При желании можно использовать другой путь к конфигурации, передав его в параметре --config, например:

$ figmagen generate --config 'Folder/figmagen.yml'

Получаемый код может быть легко кастомизирован, благодаря Stencil-шаблонам. Если возможностей стандартных шаблонов недостаточно, можно использовать собственный, указав путь к нему в конфигурации.

FigmaGen запрашивает данные файлов, используя Figma API, поэтому для генерации кода требуется интернет-соединение.

Конфигурация

Для конфигурации FigmaGen используется файл в формате YAML. В нем должны быть определены все обязательные параметры генерации кода.

Конфигурация делится на несколько разделов:

  • base: базовые параметры, используемые всеми подкомандами генерации (см. Базовые параметры).
  • colors: конфигурация подкоманды генерации цветовых стилей (см. Цветовые стили).
  • textStyles: конфигурация подкоманды генерации текстовых стилей (см. Текстовые стили).

Базовые параметры

Каждая подкоманда генерации использует следующие базовые параметры:

  • accessToken: строка с токеном доступа, необходимый для выполнения запросов Figma API (см. Токен доступа Figma).
  • fileKey: идентификатор файла Figma, данные которого будут использованы для генерации кода (см. Файл Figma).

Пример:

base:
accessToken: 27482-71b3313c-0e88-481b-8c93-0e465ab8a868fileKey: ZvsRf99Ik11qS4PjS6MAFc
...

Если какой-либо из базовых параметров отсутствует и в разделе подкоманды генерации, и в разделе base, то в результате выполнения команды figmagen generate будет получена соответствующая ошибка.

Токен доступа Figma

Для получения файлов Figma необходима авторизация, которая реализуется путём передачи персонального токена доступа. Такой токен может быть создан в несколько простых шагов:

  1. Открыть настройки аккаунта в Figma.
  2. Нажать кнопку "Create a new personal access token" в разделе "Personal Access Tokens".
  3. Ввести описание для создаваемого токена (например, "FigmaGen").
  4. Скопировать созданный токен в буфер обмена.
  5. Вставить токен доступа в поле accessToken конфигурации

Файл Figma

FigmaGen запрашивает файл Figma по его стандартному идентификатору, который может быть получен из URL в адресной строке браузера. В общем виде этот URL имеет следующий формат:

https://www.figma.com/file/<идентификатор>/<название>?node-id=<идентификатор выделенного узла>

Получив идентификатор файла, его необходимо указать в поле fileKey конфигурации.

Настройки генерации

Для каждой подкоманды генерации необходимо определить следующие параметры:

  • destinationPath: путь для сохранения сгенерированного файла.
  • templatePath: путь к файлу Stencil-шаблона. Если параметр пропущен, то будет использован стандартный шаблон.
  • includingNodes: массив строк с идентификаторами узлов, которые должны быть использованы при генерации кода. Если этот параметр пропущен, то будут использованы все узлы файла.
  • excludingNodes: массив строк с идентификаторами узлов, которые должны быть проигнорированы при генерации кода. Если этот параметр пропущен, то будут использованы все узлы файла, указанные в поле includingNodes.

Цвета

Пример конфигурации:

base:
accessToken: 27482-71b3313c-0e88-481b-8c93-0e465ab8a868fileKey: ZvsRf99Ik11qS4PjS6MAFccolors:
destinationPath: Sources/Generated/Colors.swiftincludingNodes:
- 7:24

Пример использования сгенерированного кода:

view.backgroundColor =Colors.carolina

Текстовые стили

Пример конфигурации:

base:
accessToken: 27482-71b3313c-0e88-481b-8c93-0e465ab8a868fileKey: ZvsRf99Ik11qS4PjS6MAFctextStyles:
destinationPath: Sources/Generated/TextStyle.swiftincludingNodes:
- 3:19

Пример использования сгенерированного кода:

label.attributedText ="Hello World".styled(.title1, textColor:Colors.black)

Лицензия

FigmaGen доступен для использования под лицензией MIT (см. LICENSE).

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages