将样式映射到 Compose 主题

Mapping from Styles in Figma to Theme in Compose

Figma 允许设计师将样式应用于设计元素。样式是可重用的属性集合,例如颜色或排版。由于它是集中定义的,因此团队可以在更新单个设计元素时定义和更新所有设计中的属性。您可以设置 Relay,使其将 Figma 样式转换为 Jetpack Compose 主题。

Figma 样式和 Compose 主题之间的映射通过配置文件指定。

Configuration file maps Figma styles and Compose themes

例如,以下所示的 Figma 设计使用了 Google 的 Material 3 Design Kit 中的样式。对于文本 **Primary - Title large**,字体为 **M3/title/large**,颜色为 **M3/sys/light/primary**。

Material 3 styles in Figma

如果我们在启用 M3 Design Kit 样式转换的情况下导入设计,则会为 **Primary - Title large** 文本生成以下代码

@Composable
fun PrimaryTitleLarge(modifier: Modifier = Modifier) {
    Text(
        content = "Primary - Title large",
        fontSize = MaterialTheme.typography.titleLarge.fontSize,
        fontFamily = MaterialTheme.typography.titleLarge.fontFamily,
        color = MaterialTheme.colorScheme.primary,
        height = MaterialTheme.typography.titleLarge.lineHeight,
        letterSpacing = MaterialTheme.typography.titleLarge.letterSpacing,
        textAlign = TextAlign.Left,
        fontWeight = MaterialTheme.typography.titleLarge.fontWeight,
        modifier = modifier
    )
}

要使用此功能,请像往常一样在 Figma 中使用样式。然后在 Android Studio 中,转到 **文件 > 新建 > 导入 UI 包…**,然后选中 **将 Figma 样式转换为 Compose 主题**。

此时,您必须选择一个配置来转换设计样式

  • 如果它们直接来自 Google 的 Figma Material 3 Design Kit(格式为 M3/body/medium 或 M3/sys/light/primary),则选择 **Material 3 Design Kit 配置** 选项。
  • 如果它们直接来自 Google 的 Figma Material 2 Design Kit(格式为 01. Primary/500 或 Subtitle 1),则选择 **Material 2 Design Kit 配置** 选项。
  • 如果您有自己的样式定义,则选择 **自定义配置** 选项并选择包含 Figma 样式和 Compose 主题之间映射的文件(在本节中描述)。

    Import UI Package dialog

如果 Figma 设计中存在未在所选配置中包含的样式,则导入对话框会为每个未映射的样式显示警告。每个未映射的样式都将转换为其字面值。警告最初是折叠的;单击警告横幅展开。每个警告都包含一个指向导致警告的 Figma 文件中特定图层的链接。

Warnings in the import dialog

导入后,样式配置位于 Android Studio 项目中。在 ui-package-resources/style-mappings 目录中查找它们。

自定义转换的配置文件

将 Figma 样式转换为 Compose 主题包括两个步骤

  1. UI 包中的 Figma 样式将转换为 UI 包定义 JSON 文件中的设计令牌,该文件位于 Android Studio 项目中的 UI 包文件夹内。
  2. UI 包定义文件中的设计令牌将转换为 Android Studio 项目中的 Compose 主题代码片段。

自定义配置文件(JSON 格式)的格式反映了这两个步骤。以下是一个仅处理颜色样式的简单自定义配置文件示例

{
  "figma": {
    "colors": {
      "my-app-theme/sys/light/primary": "myapp.sys.color.primary",
      "my-app-theme/sys/light/primary-container": "myapp.sys.color.primary-container",
      "my-app-theme/sys/light/background": "myapp.sys.color.background",
      "my-app-theme/sys/light/on-background": "myapp.sys.color.on-background",
      "my-app-theme/sys/dark/background": "myapp.sys.color.background",
      "my-app-theme/sys/dark/on-background": "myapp.sys.color.on-background"
    }
  },
  "compose": {
    "colors": {
      "myapp.sys.color.primary": "MaterialTheme.colorScheme.primary",
      "myapp.sys.color.primary-container": "MaterialTheme.colorScheme.primaryContainer",
      "myapp.sys.color.background": "MaterialTheme.colorScheme.background",
      "myapp.sys.color.on-background": "MaterialTheme.colorScheme.onBackground"
    },
    "options": {
      "packages": {
        "MaterialTheme": "androidx.compose.material3"
      }
    }
  }
}

有两个顶级部分,figma(指定步骤 1)和 compose(指定步骤 2)。两者都包含一个 colors 部分

  • figmacolors 部分指定了 Figma 样式以及应写入 UI 包定义文件的相应设计令牌。
  • composecolors 部分指定了 UI 包定义文件中的设计令牌以及应写入 Compose 代码的相应代码片段。

在上面的配置示例中,在 Figma 中使用颜色 my-app-theme/sys/light/primary 的任何内容都会将其颜色写为 UI 包定义文件中的 myapp.sys.color.primary。然后,在代码生成期间,该颜色在 Compose 中写为 MaterialTheme.colorScheme.primary

compose 部分还包含一个 options 部分,该部分说明特定代码符号位于哪个包中。上面的示例说明 MaterialTheme 位于 androidx.compose.material3 包中,因此应将其导入到任何生成的代码中。

排版样式的映射比颜色样式稍微复杂一些。以下与上例相同,但添加了排版样式

{
  "figma": {
    "colors": {
      "my-app-theme/sys/light/primary": "myapp.sys.color.primary",
      "my-app-theme/sys/light/primary-container": "myapp.sys.color.primary-container",
      "my-app-theme/sys/light/background": "myapp.sys.color.background",
      "my-app-theme/sys/light/on-background": "myapp.sys.color.on-background",
      "my-app-theme/sys/dark/background": "myapp.sys.color.background",
      "my-app-theme/sys/dark/on-background": "myapp.sys.color.on-background"
    },
    "typography": {
      "symbols": {
        "my-app-theme/headline/large": "myapp.sys.typescale.headline-large",
        "my-app-theme/body/medium": "myapp.sys.typescale.body-medium"
      },
      "subproperties": {
        "fontFamily": "font",
        "fontWeight": "weight",
        "fontSize": "size",
        "letterSpacing": "tracking",
        "lineHeightPx": "line-height"
      }
    }
  },
  "compose": {
    "colors": {
      "myapp.sys.color.primary": "MaterialTheme.colorScheme.primary",
      "myapp.sys.color.primary-container": "MaterialTheme.colorScheme.primaryContainer",
      "myapp.sys.color.background": "MaterialTheme.colorScheme.background",
      "myapp.sys.color.on-background": "MaterialTheme.colorScheme.onBackground"
    },
    "typography": {
      "symbols": {
        "myapp.sys.typescale.headline-large": "MaterialTheme.typography.headlineLarge",
        "myapp.sys.typescale.body-medium": "MaterialTheme.typography.bodyMedium"
      },
      "subproperties": {
        "font": "fontFamily",
        "weight": "fontWeight",
        "size": "fontSize",
        "tracking": "letterSpacing",
        "line-height": "lineHeight"
      }
    },
    "options": {
      "packages": {
        "MaterialTheme": "androidx.compose.material3"
      }
    }
  }
}

排版部分的结构反映了排版样式由许多子属性组成的事实。在 Figma 和 Compose 中,排版样式包括字体的名称、字体粗细、大小、字距和行高,以及许多其他属性。我们无需一遍又一遍地映射每个样式的各个子属性,而是将整体样式映射到令牌和主题,然后分别映射每个单独的子属性。

上面的示例说明,当将具有样式 my-app-theme/headline/large 的 Figma 文本项写入 UI 包定义文件时,文本的字体为 myapp.sys.typescale.headline-large.font,其大小为 myapp.sys.typescale.headline-large.size,依此类推。然后,在生成 Compose 代码时,将创建一个 RelayText 可组合项(它包装了 Compose Material 中的 Text 可组合项),其中 font 参数为 MaterialTheme.typography.headlineLarge.fontFamilysize 参数为 MaterialTheme.typography.headlineLarge.fontSize,依此类推。

有关配置文件的示例,您可以查看内置的 Material 3 和 Material 2 Design Kit 配置,它们使用完全相同的格式。您可以从此处下载文件

限制

目前,在某些情况下,样式不会转换为主题

  • 仅应用于文本元素一部分的文本样式(如 文本中的多个样式 中所述)
  • 如果组件的不同变体应用了不同的样式,则仅转换一个样式。