Как стать автором
Обновить
297.94
Ozon Tech
Команда разработки ведущего e‑com в России

Kelp — IDE-плагин для кастомных дизайн-систем на Jetpack Compose

Уровень сложностиПростой
Время на прочтение9 мин
Количество просмотров2.6K

Привет! Меня зовут Антон, я ведущий разработчик мобильных приложений в Ozon Tech.
Наверное, почти у каждого происходит стечение обстоятельств, которые подталкивают нас что-то сделать своё. Иногда это стол из слэба, а случается в жизни и собственный плагин. У меня было второе, и вот моя история…

Я долго работал на Android View, но жизнь безапелляционно мотивировала меня перейти к дизайн-системам на Jetpack Compose. Мне стало не хватать некоторых фич Android Studio, которые были доступны только в Android View.

«РАБОТАЕТ!» — такая громкая мысль прозвучала у меня в голове, когда всё получилось. Надеюсь, соседи этого не слышали.

Плагин для Android Studio был готов! Он был призван в этот мир для улучшения поддержки кастомных дизайн-систем на Jetpack Compose в Android Studio.
Здесь, возможно, для иллюстрации этой сцены хорошо бы прозвучал смех сумасшедшего, но очень радостного учёного. Давайте мысленно проиграем этот джингл.
Он был назван Kelp. Строго и лаконично. Мы сразу договорились, что без панибратства.

А теперь позвольте с гордостью и небольшим апломбом создателя рассказать о своём творении.

TLDR; Kelp на GitHub

Kelp предлагает широкий набор функций, которые делают разработку UI быстрее и проще.

После перехода с дизайн-систем, построенных на Android View, к дизайн-системам на Jetpack Compose я заметил, что мне не хватает некоторых фич Android Studio, которые были доступны только в Android View.

Чтобы исправить эту ситуацию, я разработал Kelp — мощный плагин для Android Studio, разработанный для улучшения поддержки кастомных дизайн-систем на Jetpack Compose в Android Studio. Kelp предлагает широкий набор функций, которые делают разработку UI быстрее и проще.

Ключевые особенности

🔧 Настраиваемые иконки для компонентных функций

Kelp позволяет устанавливать кастомные иконки для composable-функций компонентов вашей дизайн-системы. Эти иконки отображаются в выпадающем списке code completion аналогично тому, как отображаются ресурсы R.drawable. Эта декорация помогает легче идентифицировать и использовать компоненты последовательно по всему проекту.

Кастомные иконки для composable-функций в сode сompletion
Кастомные иконки для composable-функций в сode сompletion

🎨 Иконки дизайн-системы

С помощью Kelp иконки вашей дизайн-системы отображаются в выпадающем списке code completion и сбоку от строк кода (gutter) так же, как и нативные ресурсы Android drawable. Эта функция позволяет быстро находить и использовать нужные иконки, не отвлекаясь от кода.

Иконки дизайн-системы в code completion и gutter
Иконки дизайн-системы в code completion и gutter

🌈 Предпросмотр цветов

Kelp оживляет цветовую палитру вашей дизайн-системы, показывая превью цветов в выпадающем списке code completion и в gutter. Эта функция аналогична нативным ресурсам R.color, предоставляя мгновенный визуальный ориентир, который упрощает применение правильных цветов.

Цвета дизайн-системы в code completion и gutter
Цвета дизайн-системы в code completion и gutter

📱 Интеграция демоприложения

Установка и переход к демоприложению, демонстрирующему компоненты вашей дизайн-системы, становится сильно проще. Kelp автоматизирует скачивание и установку APK (соответствующей той версии дизайн-системы, которая подключена к проекту) и предоставляет Intention Action (+) и иконку в gutter для открытия конкретных страниц компонентов прямо из вашего кода.

Демоприложение через ⌥ + ↩
Демоприложение через ⌥ + ↩
Демоприложение в gutter
Демоприложение в gutter

🖼️ Рендеринг изображений в KDoc

Ещё одна крутая фича Kelp — возможность рендерить изображения в KDoc, несмотря на текущие ограничения Android Studio. Эта функция сильно прокачивает вашу документацию, позволяя добавлять картинки компонентов ДС в KDoc, что способствует их лучшему поиску, пониманию и использованию.

Рендеринг изображений в KDoc
Рендеринг изображений в KDoc

⌨️ Шаблоны кода (Live Templates)

Ускорьте написание кода с помощью настраиваемых шаблонов кода. Эти шаблоны могут быть адаптированы для включения часто используемых фрагментов кода вашей дизайн-системы, автоматически вызывая окно code completion для ускорения разработки.

Live Templates
Live Templates

А теперь к настройкам…

Kelp очень конфигурируемый. Изменяя файл config.json, вы можете адаптировать плагин под уникальные нужды вашего проекта. Эта конфигурация на основе JSON поддерживает детальную настройку — от префиксов функций для подсветки компонентов до параметров отображения цветов и иконок.

Кроме того, так как это файл, его можно хранить в Git и делиться им с командой, обеспечивая консистентность и устраняя необходимость каждому разработчику вручную настраивать плагин через интерфейс настроек Android Studio.

Вот полный конфигурационный файл с комментариями (более актуальную версию см. на GitHub):

{
  // If you want to disable some of these features, just don't include 
  // their sections to your json file.
  
  // Replacing the default icon of design system components
  // in the code completion with a customizable icon
  // Custom icon MUST be 
  // 1. an svg 
  // 2. with size — 40x40
  // 3. placed here: /.idea/kelp/dsComponentFunIcon.svg
  // 4. optionally, a dark version can be added: 
  // /.idea/kelp/dsComponentFunIcon_dark.svg
  "componentFunHighlighting": {
    // custom icon will be added to all functions in this package
    "functionFqnPrefix": "com.your.designsystem.package.components.",
    "functionSimpleNamePrefix": "Ds" // optional
  },

  // Rendering design system colors in the code completion and 
  // gutter (where breakpoints are). 
  // Like with regular Android resources.
  "colorPreview": {
    "codeCompletionEnabled": true,
    "gutterEnabled": true,
    // optional, color tokens from enum class
    "enumColorTokensEnabled": true,
  },
  
  // Rendering design system icons in the code completion and 
  // gutter (where breakpoints are). 
  // Like with regular Android resources.
  "iconsRendering": {
    "codeCompletionEnabled": true,
    "gutterEnabled": true,
    // class with a lot of properties that return icons and are 
    // named as icons
    "containerClassName": "com.your.designsystem.package.DsIcons",
    
    // optional: filters out properties that do not represent an icon
    "propertyNameFilter": {
      // optional: only properties with this prefix will be considered 
      // as an icon
      "startsWith": ["ic_"],
      // optional: all properties with this prefix will be skipped
      "doesNotStartWith": ["allIconsAsList", "otherProperty"]
    },
    
    // maps property names to drawable resource names
    "propertyToResourceMapper": {
      "addPrefix": "ic_", // optional
      "convertToSnakeCase": true // optional; e.g. "AddAccount" -> "add_account"
    }
  },
  
  // Opening the component page in the demo app via an Intention Action
  "demoApp": {
    // optional: custom name of the intention action
    "intentionName": "🚀 Open in MY CUSTOM design system demo app",
    "functionFqnPrefix": "com.your.designsystem.package.components.",
    "functionSimpleNamePrefix": "Ds", // optional
    // package name of the demo app
    "appPackageName": "com.your.designsystem.package.demo",
    // deeplink that will be used to open a component page in the demo app.
    // DS_COMPONENT_FQN_DEEPLINK_PLACEHOLDER will be replaced with
    // the fully qualified name of the 
    // composable function, e.g. com.your.designsystem.package.components.Badge
    "componentDeeplink": "yourscheme://component/DS_COMPONENT_FQN_DEEPLINK_PLACEHOLDER",
    
    // optional
    // Installing (if not installed) the apk file
    // of the demo app (showcase app) on an Android device.
    
    // Demo app apk must be placed here with 
    // this name: /.idea/kelp/demoApp-VERSION_NAME.apk
    // For example: /.idea/kelp/demoApp-0.12.0.apk
    // The plugin will acquire the latest version 
    // from the apk file name (for example, 0.12.0).
    // If the app is not installed OR installed, but has a lower
    // version, the plugin will install the apk on the device.
    "apkInstallation": true,
    // optional
    // if apkInstallation == true, and there is no apk file found, launches this gradle command.
    // If you use Kelp Gradle Plugin, value must be "kelpCheckDemoAppApk"
    "apkDownloadGradleCommand": "kelpCheckDemoAppApk"
  },
  
  // Installs live templates into the IDE.
  // Useful for writing frequent code, like "MaterialTheme.colors." in 
  // just 3 keystrokes.
  // After completion, opens code completion 
  // in place of $CODE_COMPLETION$, saving even more effort.
  "liveTemplates": [
    {
      "abbreviation": "dt",
      "text": "com.your.designsystem.DsTheme.$CODE_COMPLETION$",
      "description": "Writes \"DsTheme.\"",
      "variables": [{ "name": "CODE_COMPLETION", "expression": "complete()" }]
    },
    {
      "abbreviation": "dtc",
      "text": "com.your.designsystem.DsTheme.colors.$CODE_COMPLETION$",
      "description": "Writes \"DsTheme.colors.\"",
      "variables": [{ "name": "CODE_COMPLETION", "expression": "complete()" }]
    },
    {
      "abbreviation": "dtt",
      "text": "com.your.designsystem.DsTheme.typography.$CODE_COMPLETION$",
      "description": "Writes \"DsTheme.typography.\"",
      "variables": [{ "name": "CODE_COMPLETION", "expression": "complete()" }]
    },
    {
      "abbreviation": "dti",
      "text": "com.your.designsystem.DsTheme.icons.$CODE_COMPLETION$",
      "description": "Writes \"DsTheme.icons.\"",
      "variables": [{ "name": "CODE_COMPLETION", "expression": "complete()" }]
    },
    {
      "abbreviation": "rmso",
      "text": "$VAL_TYPE$ $NAME$ by androidx.compose.runtime.remember { androidx.compose.runtime.mutableStateOf($VALUE$) }",
      "description": "Creates mutableStateOf",
      "reformat": true,
      "variables": [
        { "name": "VAL_TYPE", "expression": "enum(\"var\", \"val\")" },
        { "name": "NAME" },
        { "name": "VALUE", "expression": "enum(\"false\", \"null\", \"0\", \"0f\")" }
      ],
      "context": ["KOTLIN_CLASS", "KOTLIN_STATEMENT", "KOTLIN_TOPLEVEL"]
    }
  ]
}

Рекомендации по установке, если вы решились попробовать Kelp.

🛠️Инструкция по установке находится здесь.

🐘 Gradle Plugin

В дополнение к IDE-плагину вы можете дополнительно использовать сопутствующий gradle-плагин. Он имеет 2 функции/gradle tasks:

  1. kelpCheckIdePluginPresence — уведомляет разработчика, если плагин Kelp IDE отсутствует или имеет неправильную версию. Может привести к build fail или вывести предупреждение в консоль;

  2. kelpCheckDemoAppApk — проверяет наличие и версию apk-файла демоприложения дизайн-системы. Загружает его при необходимости.

Вы можете включить/отключить эти функции независимо.

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

Kelp на Gradle Plugin Portal

// в build.gradle.kts модуля приложения, который разработчики часто компилируют для запуска приложения
plugins {
    id("ru.ozon.kelp") version "0.0.4"
}

kelp {
    idePluginAbsenceBehaviour = IdePluginAbsenceBehaviour.WARNING // NOTHING, WARNING, BUILD_FAIL
    requiredIdePluginVersion = "1.0.0"
    requiredDemoApkVersion = "1.3.0" // libs.versions.yourDesignSystem.get()

    // Если файл apk можно скачать без необходимости входа через веб-браузер, используйте SimpleApkDownloader:
    setApkDownloader(
        SimpleApkDownloader(
            additionalErrorMsg = "Убедитесь, что корпоративный VPN включен", // опционально
            urlProvider = { version -> "https://example.com/demo-$version.apk" },
        ),
    )
  
    // В других случаях, когда требуются ручные действия с браузером, используйте BrowserApkDownloader:
    setApkDownloader(BrowserApkDownloader { version -> "https://example.com/?query=android/$version" })
  
    // Это сделает следующее:
    // 1. Откроет указанный URL в браузере
    // 2. Попросит пользователя скачать apk
    // 3. Будет отслеживать появление нового файла ".apk" в папке загрузок
    // 4. Скопирует его в [destinationDir] с именем [fileName].
  
    // Вы также можете реализовать полностью кастомный ApkDownloader:
    setApkDownloader(ApkDownloader { version, destinationDir, fileName, logger ->
        // ...
        file("ваш apk файл").copyTo(destinationDir.resolve(fileName))
    })
}

🚚 Как выбрать способ распространения apk демоприложения? Задаём себе вопросы.

Flowchart
Flowchart

1️⃣ Находится ли ваша дизайн-система в отдельном репозитории? Если нет, то установка демоприложения на данный момент не поддерживается.

Можно сделать следующее:

  • включить gradle-модуль демоприложения в debug-сборку вашего приложения. В этом случае Kelp просто откроет deeplink в ваше приложение;

  • надеяться, что разработчики установят демоприложение вручную.

2️⃣ Сколько клиентов используют библиотеку вашей дизайн-системы?

  • Если есть только один пользователь, и команда дизайн-системы ответственна за обновление версий в репозитории клиента, вы можете добавить последний apk демоприложения в git (возможно, используя git lfs) и обновлять его с новой версией при каждом изменении версии библиотеки. Таким образом, у всех будет актуальный apk-файл в каталоге /.idea/kelp/apk.

  • Если у вас много клиентов, и они обновляют версию библиотеки самостоятельно, вы можете порекомендовать им интегрировать Kelp Gradle Plugin и настроить его с использованиемSimpleApkDownloader или BrowserApkDownloader.

3️⃣ Насколько просто скачать apk демоприложения?

Рекомендую публиковать apk-файл демоприложения вместе с .aar-файлом библиотеки дизайн-системы в maven

В этом случае можно использовать SimpleApkDownloader.

Как это сделать?

  • Если apk демоприложения можно скачать по прямой ссылке (возможно, доступной только через корпоративный VPN), вы можете использовать SimpleApkDownloader и не добавлять apk в git. Это обеспечит автоматическую загрузку последнего apk демоприложения для всех разработчиков, работающих над проектами, которые зависят от вашей дизайн-системы.

  • В противном случае, если для загрузки apk требуются ручные действия через браузер, используйтеBrowserApkDownloader и добавьте apk в git.

    Когда владелец проекта выполнит обновление версии дизайн-системы и соберёт приложение, Kelp Gradle Plugin обнаружит несовпадение между старой версией apk демоприложения и новой версией дизайн-системы.

    Плагин откроет браузер и попросит владельца проекта скачать apk. Плагин автоматически обнаружит его появление в папке Downloads, переименует и скопирует его в проект.

    Наконец, владелец проекта закоммитит изменения версии вместе с новым apk в git.

    В этом случае BrowserApkDownloader упрощает задачу обновления дизайн-системы до новой версии. Владелец проекта больше не должен обращаться к документации дизайн-системы для получения ссылки на скачивание apk и ручного размещения apk в проекте.

🚀 Повышайте эффективность разработки

Kelp существенно повышает удовольствие от взаимодействия с дизайн-системой внутри Android Studio. Предоставляя визуальные подсказки и удобный доступ к ресурсам ДС прямо в IDE, он сокращает время поиска нужных компонентов.

Kelp помогает добиться консистентности, улучшает читаемость кода и в конечном итоге позволяет быстрее создавать качественные продукты.

Более подробная информация и примеры конфигурации —Kelp на GitHub.

Если вам нравится Kelp, я буду признателен за ⭐️ на GitHub!

Удачной разработки! 👋

Теги:
Хабы:
+11
Комментарии1

Публикации

Информация

Сайт
ozon.tech
Дата регистрации
Дата основания
Численность
5 001–10 000 человек
Местоположение
Россия