Documentación

Exportaciones nativas

Un solo comando convierte los iconos de glyphfox en assets vectoriales de verdad para Android, Jetpack Compose, iOS, SwiftUI y Flutter. El grosor, las esquinas, el duotono, los modificadores y las fusiones se exportan como paths simples, y los trazos siguen siendo trazos.

Resumen

terminal
npx glyphfox export android home search file+check --out app/src/main/res
npx glyphfox export compose --from icons.txt --package com.acme.icons --out app/src/main/java
npx glyphfox export ios home search --out MyApp/Assets.xcassets
npx glyphfox export swiftui home search --out MyApp
npx glyphfox export flutter home search --out .
npx glyphfox export android --all --weight 1.5 --corners sharp --out app/src/main/res

Pasa nombres de iconos o cualquier spec de la sintaxis de nombres, un archivo de lista con --from (un nombre por línea, # inicia un comentario) o --all para todo el conjunto. La geometría es la misma que dibujan los paquetes web, así que las mismas specs se ven igual en todas partes:

heart
bell/duotone
file+check
cloud&lock
user+plus@tl
DestinoEscribe en --outÚsalo como
androiddrawable/gf_NAME.xml@drawable/gf_home, R.drawable.gf_home
composePACKAGE/GlyphFox.kt y PACKAGE/NAME.ktIcon(GlyphFox.Home, null)
iosGlyphFox.xcassets/gf-NAME.imagesetUIImage(named: "gf-home")
swiftuiGlyphFox.swift y el catálogoImage(glyphfox: .home)
flutterassets/glyphfox/NAME.svg y lib/glyphfox.dartGlyphFoxIcon(GlyphFoxIcons.home)

Android

Un VectorDrawable por icono en drawable/, así que apunta --out a app/src/main/res. Los trazos conservan su grosor en unidades del viewport, sus remates y uniones redondeados o rectos, y nunca reciben relleno, así que escalan con el drawable exactamente como el SVG. El color es un tinte: ?attr/colorControlNormal por defecto, así que los iconos siguen el tema como los iconos Material.

res/drawable/gf_heart.xml
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24"
    android:tint="?attr/colorControlNormal">
    <path
        android:pathData="M12,19.89 L4.41,12.3 A4.8,4.8,0,1,1,12,6.58 A4.8,4.8,0,1,1,19.59,12.3 Z"
        android:strokeColor="@android:color/white"
        android:strokeWidth="2"
        android:strokeLineCap="round"
        android:strokeLineJoin="round" />
</vector>
layout.xml
<ImageView
    android:layout_width="24dp"
    android:layout_height="24dp"
    android:src="@drawable/gf_heart"
    android:contentDescription="@string/favorite" />

Pasa un atributo de tema o un recurso de color en --color (?attr/colorPrimary, @color/brand) para usarlo como tinte, o un color hex (#ff7a1a) para fijar el color en los paths sin tinte. Las capas duotono son paths rellenos con fillAlpha, --mirror-rtl activa android:autoMirrored, y la rotación y los volteos se convierten en un grupo alrededor del centro.

Jetpack Compose

GlyphFox.kt declara el objeto GlyphFox y cada icono es una propiedad de extensión ImageVector sobre él, construida en el primer uso y guardada en caché, en su propio archivo. Los archivos van a la carpeta del paquete dentro de --out, así que apunta esa opción a la raíz del código fuente Kotlin.

com/acme/icons/Heart.kt
package com.acme.icons

val GlyphFox.Heart: ImageVector
    get() {
        if (_heart != null) {
            return _heart!!
        }
        _heart = ImageVector.Builder(
            name = "GlyphFox.Heart",
            defaultWidth = 24.dp,
            defaultHeight = 24.dp,
            viewportWidth = 24f,
            viewportHeight = 24f,
        ).apply {
            path(
                stroke = SolidColor(Color.Black),
                strokeLineWidth = 2f,
                strokeLineCap = StrokeCap.Round,
                strokeLineJoin = StrokeJoin.Round,
            ) {
                moveTo(12f, 19.89f)
                lineTo(4.41f, 12.3f)
                arcTo(4.8f, 4.8f, 0f, true, true, 12f, 6.58f)
                arcTo(4.8f, 4.8f, 0f, true, true, 19.59f, 12.3f)
                close()
            }
        }.build()
        return _heart!!
    }

private var _heart: ImageVector? = null
Screen.kt
import com.acme.icons.GlyphFox
import com.acme.icons.Heart

Icon(GlyphFox.Heart, contentDescription = "Favorite")
Icon(GlyphFox.Heart, contentDescription = null, tint = MaterialTheme.colorScheme.primary)
Image(GlyphFox.Heart, contentDescription = null) // keeps the exported color

GlyphFox.all.forEach { (name, vector) -> Icon(vector, contentDescription = name) }

Cada propiedad se importa por nombre, como los iconos Material. GlyphFox.all asocia cada nombre exportado con su vector para selectores y vistas previas. Con la reducción de código activada, R8 elimina los iconos que una app nunca usa, salvo que lea GlyphFox.all.

Catálogo de assets de iOS

Un image set por icono con el SVG, Preserve Vector Data y Render As Template Image, así que los iconos se ven nítidos a cualquier tamaño y toman el color de tinte. Apunta --out a un catálogo existente como MyApp/Assets.xcassets para añadirle los image sets (su propio Contents.json se conserva), o a una carpeta para obtener GlyphFox.xcassets.

gf-heart.imageset/Contents.json
{
  "images" : [
    {
      "filename" : "gf-heart.svg",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "preserves-vector-representation" : true,
    "template-rendering-intent" : "template"
  }
}
ViewController.swift
let heart = UIImageView(image: UIImage(named: "gf-heart"))
heart.tintColor = .systemOrange

Los archivos SVG llevan colores concretos (negro por defecto), que el renderizado como plantilla sustituye por el tinte. Con un --color hex, el catálogo pasa al renderizado original para que se vea el color; --rendering template u original elige uno de forma explícita, y --mirror-rtl marca los image sets para que se reflejen en layouts de derecha a izquierda.

SwiftUI

glyphfox export swiftui escribe el mismo catálogo de assets y además GlyphFox.swift: un enum con un case por image set, Image(glyphfox:) y UIImage.glyphfox(_:) para UIKit.

GlyphFox.swift
public enum GlyphFox: String, CaseIterable, Sendable {
    case heart = "gf-heart"
    case `repeat` = "gf-repeat"
}

public extension Image {
    init(glyphfox icon: GlyphFox, bundle: Bundle? = nil) {
        self = Image(icon.rawValue, bundle: bundle).renderingMode(.template)
    }
}
ContentView.swift
Label { Text("Favorites") } icon: { Image(glyphfox: .heart) }

Image(glyphfox: .heart)
    .resizable()
    .frame(width: 32, height: 32)
    .foregroundStyle(.orange)
    .accessibilityLabel("Favorite")

ForEach(GlyphFox.allCases, id: \.self) { Image(glyphfox: $0) }

Pasa bundle: .module cuando el catálogo esté en un paquete Swift.

Flutter

Archivos SVG en assets/glyphfox/ y lib/glyphfox.dart con una constante por icono y un pequeño widget GlyphFoxIcon sobre flutter_svg. Apunta --out a la carpeta de la app y luego añade el paquete y los assets a pubspec.yaml:

pubspec.yaml
dependencies:
  flutter_svg: ^2.0.0

flutter:
  assets:
    - assets/glyphfox/
main.dart
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'glyphfox.dart';

Row(children: [
  const GlyphFoxIcon(GlyphFoxIcons.heart),
  GlyphFoxIcon(GlyphFoxIcons.heart, size: 32, color: Colors.orange, semanticLabel: 'Favorite'),
  SvgPicture.asset(GlyphFoxIcons.heart), // the exported colors, no tint
])

GlyphFoxIcon sigue al IconTheme que lo rodea en tamaño y color, como hace Icon, tiñe todo el dibujo (la capa duotono conserva su opacidad) y es decorativo salvo que reciba un semanticLabel. GlyphFoxIcons.values lista todas las rutas exportadas, y --assets cambia la carpeta de los SVG.

Opciones

OpciónDestinosPor defectoDescripción
specstodosNombres o specs como file+check@tr, cloud&lock:side o heart/duotone.
--fromtodosUn archivo de lista: un nombre por línea o separados por comas, # inicia un comentario.
--alltodosTodos los iconos del conjunto.
--outtodos.La carpeta del proyecto: res para android, la raíz del código fuente Kotlin para compose, una carpeta o un catálogo .xcassets para ios y swiftui, la carpeta de la app para flutter.
--sizetodos24Tamaño en dp, puntos o píxeles lógicos. Por debajo de 24 el trazo se compensa ópticamente, como en la web.
--weighttodos2Grosor del trazo de 1 a 3 en la cuadrícula de 24.
--absolute-weighttodosMantiene el trazo en unidades de grosor al tamaño de exportación.
--cornerstodosroundround o sharp (remates cuadrados y uniones en inglete).
--varianttodosoutlineoutline o duotone. El estilo sólido recorta líneas con máscaras, que VectorDrawable e ImageVector no pueden dibujar, así que se rechaza.
--colortodostinteUn color hex fijado en los archivos. Android también acepta un atributo de tema o un recurso de color, que se usa como tinte.
--secondary-color, --secondary-opacitytodosel color, 0.3Color y opacidad de la capa duotono.
--rotate, --flip-x, --flip-ytodosUna transformación alrededor del centro de la cuadrícula.
--mirror-rtltodosRefleja el icono en layouts de derecha a izquierda (autoMirrored, autoMirror, la dirección del image set).
--modifier, --modifier-cornertodosLa misma insignia en todos los iconos, como file+check.
--prefixandroid, ios, swiftuigf_, gf-Prefijo de los nombres de los drawables o de los image sets.
--packagecomposeglyphfoxPaquete Kotlin, que también es la carpeta dentro de --out.
--renderingios, swiftuitemplatetemplate u original; original es el valor por defecto con un --color hex.
--assetsflutterassets/glyphfoxCarpeta de los archivos SVG y de las rutas de las constantes.

Nombres y colores

Una spec se convierte en un nombre en cada plataforma: file+check@tr es gf_file_check_tr en Android, GlyphFox.FileCheckTr en Compose, gf-file-check-tr en el catálogo y fileCheckTr en Swift y Dart. Dos specs que acaban con el mismo nombre se rechazan, y las palabras clave se escapan (repeat pasa a ser `repeat` en Swift).

Sin --color, cada destino sigue el tinte de la plataforma: colorControlNormal, LocalContentColor, el foreground style de SwiftUI o IconTheme. Con un color hex, el color queda fijado y se mantiene: Android quita el tinte, el catálogo renderiza el original y GlyphFoxIcon conserva los colores exportados salvo que reciba un color. Icon() de Compose siempre tiñe, así que usa Image() o tint = Color.Unspecified para ver el color fijado.