Style-dictionary: Support for Android Jetpack Compose

Created on 19 Oct 2020  路  6Comments  路  Source: amzn/style-dictionary

Jetpack Compose is the future of Android UI development, and I'd love to see first-class support for Compose in style dictionary.

While Jetpack Compose has an interop layer with style resources, I would love to see a more idiomatic integration.

For example, today with Compose + Style Dictionary we could do:

@Composable
fun TextExample() {
  Text(
    text = "Hello World",
    color = colorResource(R.color.color_font_base)
}

But I would much rather have Style Dictionary generate a Kotlin file containing the colors so we can have something like this:

@Composable
fun TextExample() {
  Text(
    text = "Hello World",
    color = StyleDictionary.colors.font.base
}
enhancement example code format help wanted integration transform transformGroup

Most helpful comment

My team is using the style dictionary and is also interested in first-class Jetpack Compose support. Bumping this thread in case anyone is able to prioritize it.

All 6 comments

I think having a Kotlin support would be awesome! Totally agree that having a more idiomatic integration would be great. The power of design tokens is that developers consuming them on different platforms should interact with them as if they were native to the platform.

If you have the time, you can open a PR to add transforms and formats to support Kotlin/Jetpack Compose. A good example PR is this one adding Flutter support: #320.

My team is using the style dictionary and is also interested in first-class Jetpack Compose support. Bumping this thread in case anyone is able to prioritize it.

I noticed that @dbanksdesign's comment was posted in October before his recent contribution to Style Dictionary v3.0 which adds support for an android resources format. https://github.com/amzn/style-dictionary/pull/509 (Thanks!)

When this Jetpack Compose feature is implemented, it would be great to offer similar functionality that creates Kotlin files based on a custom Filter. This allows developers to specify the _type_ (String, Int, Color) and _units_ (dp, sp, none) for their Style Dictionary setup.

Currently, the production version of the Style Dictionary is a bit lacking because the Android transformGroup requires your project to use color, size, etc as your top-level token category names. (I'm not sure if that is the case for other platforms). As the PR and related Issue notes, if your design system had a different naming convention, the result was that no tokens were generated in the output. I think it's still a nice feature to have for those who use it, but we should also continue to support the same functionality as #509 here, too.

@dbanksdesign I've been starting to look at this again, particularly with respect to colors and light/dark modes. I've also poked around at #399 and #307 . I'm interested in hearing your thoughts on how to make light/dark mode work for Compose.

Adding support for light/dark mode in the Android resource system should be fairly straightforward, since we can easily create separate colors.xml resource files in the values and values-night configurations.

Compose is a bit of a different beast- in a perfect Compose world we wouldn't be touching resources at all and all our colors would be defined in Kotlin files.

The way Material approaches colors in Compose is to have a Colors class that contains the semantic names for each of the colors, like so:

class Colors(
  val primary: Color
)

You would then configure light and dark mode variants by creating instances of this class:

object Palette {
   val orange = Color(0xffff781f)
   val orangeDark = Color(0xffff9d5c)
}

val lightColors = Colors(
  primary = Palette.orange
)

val darkColors = Colors(
  primary = Palette.orangeDark
)

Ideally what I want from Style Dictionary is a structure that looks like this for the themed colors, with:

  • Any color token that is _not_ themeable added to a static object so we can reference them anywhere without light/dark information
  • Themeable colors added to a class (with no value by default)
  • light/dark variants that are instances of that themeable colors class

The other side of the equation is what this should look like in a Style Dictionary JSON style properties file-

Maybe something like this?

{ 
  "color": {
    "palette": {
      "orange":  { "value": "#ff781f" },
      "orangeDark":  { "value": "#ff781f" },
    },

    "theme": {
      "primary": {
        "themeable": true,
        "light": { "value": "{color.palette.orange}" },
        "dark": { "value": "{color.palette.orangeDark}" }
      }
    }
  }
}

I took a swing at what a format that supports dark mode in Compose might look like based on your work-in-progress dark mode repo:

https://gist.github.com/bherbst/1b8c9a66953f25044631db68dd773429

There's a bit of awkward juggling to get the references to the Palette object when constructing the light/dark Colors objects, but overall I think it is workable.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

clepore picture clepore  路  5Comments

sarah-martinellibenedetti picture sarah-martinellibenedetti  路  4Comments

chazzmoney picture chazzmoney  路  4Comments

limitlessloop picture limitlessloop  路  4Comments

dbanksdesign picture dbanksdesign  路  5Comments