Valkyrie icon indicating copy to clipboard operation
Valkyrie copied to clipboard

IntelliJ IDEA / Android Studio plugin to convert SVG/XML into Compose ImageVector and previewer

Plugin Homepage Version GitHub releases Downloads License Downloads

Icon

Valkyrie

Intellij IDEA / Android Studio plugin to generate Compose ImageVector from SVG/XML

Key features

  • Support conversion from SVG and XML
  • Streamlined code formatting for generated icon:
    • remove redundant code (e.g. public keyword)
    • remove unused imports
    • skip default ImageVector parameters
    • support generation as Backing property or Lazy property
  • Two conversion modes: Simple and IconPack
  • Build-in ImageVector previewer with basic zoom and change background actions
  • Built using Compose Multiplatform and Tiamat navigation library

Simple mode

[!NOTE] One-click solution to convert SVG/XML to ImageVector (requires only specifying the package). Enables previewing the generated icon and easily copying the result to the clipboard for seamless integration into your project.

Live demo:

https://github.com/user-attachments/assets/15ee9356-0db3-4b87-b4fe-23bb6bba70a0

IconPack mode

New icon pack

[!NOTE] Facilitates creating an organized icon pack with extension properties for your pack object, previewing the list of icons, and batch exporting them to your specified directory.

Live demo:

https://github.com/user-attachments/assets/ccb568a4-bda9-4f2b-bf40-29b1a8e4c854

Existing icon pack

[!NOTE] Instead of importing icon pack settings, the plugin provides a direct way to import an already created icon pack from a Kotlin file.

[!IMPORTANT] Currently, editing features are limited; you can only load an existing pack and add more nested packs.

Live demo:

https://github.com/user-attachments/assets/77f449dd-a6d0-44ea-9059-b7b30ee94426

Export formats

Original Discussion

Backing property Lazy property
package io.github.composegears.valkyrie.playground.icons.backing.outlined

import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.path
import androidx.compose.ui.unit.dp
import io.github.composegears.valkyrie.playground.icons.backing.BackingIcons

val BackingIcons.Outlined.Add: ImageVector
  get() {
    if (_Add != null) {
      return _Add!!
    }
    _Add = ImageVector.Builder(
      name = "Outlined.Add",
      defaultWidth = 24.dp,
      defaultHeight = 24.dp,
      viewportWidth = 24f,
      viewportHeight = 24f,
    ).apply {
      path(fill = SolidColor(Color(0xFF232F34))) {
        moveTo(19f, 13f)
        lineTo(13f, 13f)
        lineTo(13f, 19f)
        lineTo(11f, 19f)
        lineTo(11f, 13f)
        lineTo(5f, 13f)
        lineTo(5f, 11f)
        lineTo(11f, 11f)
        lineTo(11f, 5f)
        lineTo(13f, 5f)
        lineTo(13f, 11f)
        lineTo(19f, 11f)
        lineTo(19f, 13f)
        close()
      }
    }.build()

    return _Add!!
  }

@Suppress("ObjectPropertyName")
private var _Add: ImageVector? = null
package io.github.composegears.valkyrie.playground.icons.lazy.outlined

import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.path
import androidx.compose.ui.unit.dp
import io.github.composegears.valkyrie.playground.icons.lazy.LazyIcons

val LazyIcons.Outlined.Add: ImageVector by lazy(LazyThreadSafetyMode.NONE) {
  ImageVector.Builder(
    name = "Outlined.Add",
    defaultWidth = 24.dp,
    defaultHeight = 24.dp,
    viewportWidth = 24f,
    viewportHeight = 24f,
  ).apply {
    path(fill = SolidColor(Color(0xFF232F34))) {
      moveTo(19f, 13f)
      lineTo(13f, 13f)
      lineTo(13f, 19f)
      lineTo(11f, 19f)
      lineTo(11f, 13f)
      lineTo(5f, 13f)
      lineTo(5f, 11f)
      lineTo(11f, 11f)
      lineTo(11f, 5f)
      lineTo(13f, 5f)
      lineTo(13f, 11f)
      lineTo(19f, 11f)
      lineTo(19f, 13f)
      close()
    }
  }.build()
}

Comparison with other solutions

Source SVG icon:

<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#e8eaed">
  <path d="M0 0h24v24H0V0z" fill="none"/>
  <path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
</svg>

ImageVector output:

Valkyrie composables.com
package io.github.composegears.valkyrie

import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.path
import androidx.compose.ui.unit.dp
import kotlin.Suppress

val Add: ImageVector
  get() {
    if (_Add != null) {
      return _Add!!
    }
    _Add = ImageVector.Builder(
      name = "Add",
      defaultWidth = 24.dp,
      defaultHeight = 24.dp,
      viewportWidth = 24f,
      viewportHeight = 24f
    ).apply {
      path(fill = SolidColor(Color(0xFFE8EAED))) {
        moveTo(19f, 13f)
        horizontalLineToRelative(-6f)
        verticalLineToRelative(6f)
        horizontalLineToRelative(-2f)
        verticalLineToRelative(-6f)
        horizontalLineTo(5f)
        verticalLineToRelative(-2f)
        horizontalLineToRelative(6f)
        verticalLineTo(5f)
        horizontalLineToRelative(2f)
        verticalLineToRelative(6f)
        horizontalLineToRelative(6f)
        verticalLineToRelative(2f)
        close()
      }
    }.build()

    return _Add!!
  }

@Suppress("ObjectPropertyName")
private var _Add: ImageVector? = null

import androidx.compose.runtime.Composable
import androidx.compose.foundation.Image
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.StrokeJoin
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.vector.path
import androidx.compose.ui.unit.dp

private var _Add: ImageVector? = null

public val Add: ImageVector
  get() {
    if (_Add != null) {
      return _Add!!
    }
    _Add = ImageVector.Builder(
      name = "Add",
      defaultWidth = 24.dp,
      defaultHeight = 24.dp,
      viewportWidth = 24f,
      viewportHeight = 24f
    ).apply {
      path(
        fill = null,
        fillAlpha = 1.0f,
        stroke = null,
        strokeAlpha = 1.0f,
        strokeLineWidth = 1.0f,
        strokeLineCap = StrokeCap.Butt,
        strokeLineJoin = StrokeJoin.Miter,
        strokeLineMiter = 1.0f,
        pathFillType = PathFillType.NonZero
      ) {
        moveTo(0f, 0f)
        horizontalLineToRelative(24f)
        verticalLineToRelative(24f)
        horizontalLineTo(0f)
        verticalLineTo(0f)
        close()
      }
      path(
        fill = SolidColor(Color(0xFFE8EAED)),
        fillAlpha = 1.0f,
        stroke = null,
        strokeAlpha = 1.0f,
        strokeLineWidth = 1.0f,
        strokeLineCap = StrokeCap.Butt,
        strokeLineJoin = StrokeJoin.Miter,
        strokeLineMiter = 1.0f,
        pathFillType = PathFillType.NonZero
      ) {
        moveTo(19f, 13f)
        horizontalLineToRelative(-6f)
        verticalLineToRelative(6f)
        horizontalLineToRelative(-2f)
        verticalLineToRelative(-6f)
        horizontalLineTo(5f)
        verticalLineToRelative(-2f)
        horizontalLineToRelative(6f)
        verticalLineTo(5f)
        horizontalLineToRelative(2f)
        verticalLineToRelative(6f)
        horizontalLineToRelative(6f)
        verticalLineToRelative(2f)
        close()
      }
    }.build()
    return _Add!!
  }

Requirements

  • IntelliJ IDEA 2024.1+
  • Android Studio Koala+

[!IMPORTANT] K2 mode is available starting from IntelliJ IDEA 2024.2.1 (more details)

Installation

Get from Marketplace
  • Find plugin inside IDE:

    Settings/Preferences > Plugins > Marketplace > Search for " Valkyrie" > Install Plugin

  • Manually: Download the latest release or build your self and install it manually using Settings -> Plugins -> ⚙️ -> Install plugin from disk...

Building

Use ./gradlew buildPlugin to build plugin locally. Artifact will be available in idea-plugin/build/distributions/ path

other available gradle commands:

  • run plugin in IDE: ./gradlew runIde

  • run tests: ./gradlew test

  • check code style: ./gradlew spotlessCheck

  • apply formatting: ./gradlew spotlessApply

Join our community

Slack

Contributors

Thank you for your help! ❤️

License

Developed by ComposeGears 2024

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.