question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

How to deal with opacity, shadow and other tokens for iOS and Android?

See original GitHub issue

Hello!

We have opacity tokens in our Design System. To generate CSS and SCSS variables its’s ok, but how can we deal with opacity tokens for iOS and Android?

Example JSON

{
  "opacity": {
    "8": { "value": ".8" },
    "6": { "value": ".6" },
    "4": { "value": ".4" },
    "1": { "value": ".16" }
  }
}

Generates

$opacity-1: .16;
$opacity-4: .4;
$opacity-6: .6;
$opacity-8: .8;

Or shadow tokens

{
  "shadow": {
    "level-1": { "value": "0 4px 8px 0 rgba (0, 0, 0, 0.10)" },
    "level-2": { "value": "0 8px 16px 0 rgba (0, 0, 0, 0.10)" },
    "level-3": { "value": "0 16px 32px 0 rgba (0, 0, 0, 0.10)" },
    "level-4": { "value": "0 32px 64px 0 rgba (0, 0, 0, 0.10)" }
  }
}

That generates

$shadow-level-1: 0 4px 8px 0 rgba (0, 0, 0, 0.10);
$shadow-level-2: 0 8px 16px 0 rgba (0, 0, 0, 0.10);
$shadow-level-3: 0 16px 32px 0 rgba (0, 0, 0, 0.10);
$shadow-level-4: 0 32px 64px 0 rgba (0, 0, 0, 0.10);

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:3
  • Comments:7 (1 by maintainers)

github_iconTop GitHub Comments

10reactions
davidyeisercommented, Nov 19, 2020

For more complex token like shadows or gradients I typically store the tokens as an array or object and then write custom transforms depending on which platform you need to support.

To take your shadows for example you could store the tokens like so:

{
  "shadow": {
    "level-1": {
      "value": {
        "x": 0,
        "y": 4,
        "blur": 8,
        "spread": 0,
        "color": "#000000",
        "opacity": 0.1
      }
    },
    "level-2": "..."
  }
}

And then your custom transforms can access the individual values as needed. For the web it would look something like this (haven’t actually tested):

const tinycolor = require('tinycolor2')

StyleDictionary.registerTransform({
  name: 'shadow/scss',
  type: 'value',
  matcher: function(prop) {
    return prop.attributes.category === 'shadow';
  },
  transformer: function(prop) {
    // destructure shadow values from original token value
    const {
      x,
      y,
      blur,
      spread,
      color,
      alpha
    } = prop.original.value
    
    // convert hex code to rgba string
    const shadowColor = tinycolor(color)
    shadowColor.setAlpha(alpha)
    shadowColor.toRgbString()
    
    return `${x}px ${y}px ${blur}px ${spread}px ${shadowColor}`
  }
});

For Android/iOS it would be a similar pattern though you may need to look into custom formats and templates for those depending on what the desired outcome looks like.

7reactions
swashcapcommented, Apr 19, 2021

Here’s the custom shadow transformer I wrote for our token project:

// configuration/shadowTransform.js 
const styleDictionary = require("style-dictionary");
const tinycolor = require("tinycolor2");

const toPx = (value) =>
  styleDictionary.transform["size/remToPx"].transformer({ value });

const shadowMatcher = (prop) => prop.attributes.category === "shadow";

const webShadowTransformer = (prop) => {
  const {
    blurRadius,
    color,
    offsetX,
    offsetY,
    spreadRadius,
  } = prop.original.value;

  return `${toPx(offsetX)} ${toPx(offsetY)} ${toPx(blurRadius)} ${toPx(
    spreadRadius
  )} ${tinycolor(color).toRgbString()}`;
};

module.exports.shadowCSSTransform = {
  matcher: shadowMatcher,
  name: "shadow/css",
  transformer: webShadowTransformer,
  type: "value",
};

module.exports.shadowSCSSTransform = {
  matcher: shadowMatcher,
  name: "shadow/scss",
  transformer: webShadowTransformer,
  type: "value",
};

These get plugged into the project’s config, like so:

// configuration/index.js
module.exports = {
  transform: {
    "shadow/css": shadowCSSTransform,
    "shadow/scss": shadowSCSSTransform,
  },
  // ...
}

…and individual config.platforms use them. Seems to work pretty well (for web).

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to manage your Design Tokens with Style Dictionary
Recently I have come across a tool, called Style Dictionary, developed by Danny Banks at Amazon, that allows you to manage design tokens...
Read more >
Xamarin.Tips – Android Shadows on Transparent Views
Xamarin.Tips – Android Shadows on Transparent Views · 1. Adjust the margin and padding to allow us to expand the frame of the...
Read more >
Shadows and Color Opacity - SwiftUI Handbook - Design+Code
Using the Color plus opacity technique, you can easily make your drop shadows using the same color as your card's color. .shadow(color: Color....
Read more >
Design Tokens - Lightning Design System
Design tokens are the visual design atoms of the design system ... Transparent value of BRAND_PRIMARY at 10% ... Use shadow tokens to...
Read more >
Design tokens on your design system | by Gonzalo Vásquez
“In the world of UI, design tokens are subatomic particles. The design token color-brand-blue is a critical ingredient of a UI, but it's...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found