Telefonica / mistica-design

Mística Design System (only design)
https://brandfactory.telefonica.com/mistica
21 stars 4 forks source link

Support gradients in tokens #1689

Closed yceballost closed 6 months ago

yceballost commented 7 months ago

This issue aims to align the needs of the three platforms (Android, iOS and Web) and design to be able to include gradients in Mística skins through token files.

Design needs

Already discussed

aweell commented 7 months ago

In Figma the expected result is:

{
  "tokenName": {
    "value": "linear-gradient({deg}, {color-1.value(hex)} {color-1.position(%)}, {color-2.value(hex)} {color-2.position(%)}, )",
    "type": "color"
  }
} 
atabel commented 7 months ago

currently, we have this for regular color tokens:

"backgroundBrand": {
    "type": "color",
    "value": "{palette.blauBluePrimary}",
    "description": "blauBluePrimary"
},

I propose something like this for gradients (pseudo json/ts syntax):

"backgroundBrand": {
    "type": "linear-gradient",
    "value": {
        "angle": number, // Angle in degrees. 0 means from bottom to top; increasing values rotate clockwise from there.
        "colors": Array<{
            "stop": number, // stop position of the color in the gradient. From 0 to 1 (0 means 0% and 1 means 100%)
            "value": string, // a palette color reference "{palette.whatever}", or a palette color with opacity "rgba({palette.whatever}, 0.2)"
        }>,
    },
    "description": "whatever"
},

for reference: https://developer.mozilla.org/en-US/docs/Web/CSS/gradient/linear-gradient

Example:

"backgroundBrand": {
    "type": "linear-gradient",
    "value": {
        "angle": 180,
        "colors": [
            {"value": "{palette.mycolor1}", "stop": 0},
            {"value": "{palette.mycolor2}", "stop": 0.3},
            {"value": "rgba({palette.mycolor3}, 0.2)", "stop": 1},
        ],
    },
    "description": "whatever"
},

In css, this would translate to something like this:

linear-gradient(180deg, #FABADA 0%, #F2E377 30%, rgba(255, 238, 170, 0.2) 100%)

Updated: don't support hex colors, only palette colors, with or without opacity

amegias commented 7 months ago

currently, we have this for regular color tokens:

"backgroundBrand": {
    "type": "color",
    "value": "{palette.blauBluePrimary}",
    "description": "blauBluePrimary"
},

I propose something like this for gradients (pseudo json/ts syntax):

"backgroundBrand": {
    "type": "linear-gradient",
    "value": {
        "angle": number, // Angle in degrees. 0 means from bottom to top; increasing values rotate clockwise from there.
        "colors": Array<{
            "stop": number, // stop position of the color in the gradient. From 0 to 1 (0 means 0% and 1 means 100%)
            "value": string, // the color in hex ("#FABADA") or a palette color reference ("{palette.whatever}")
        }>,
    },
    "description": "whatever"
},

for reference: https://developer.mozilla.org/en-US/docs/Web/CSS/gradient/linear-gradient

Example:

"backgroundBrand": {
    "type": "linear-gradient",
    "value": {
        "angle": 180,
        "colors": [
            {"value": "#FABADA", "stop": 0},
            {"value": "#F2E377", "stop": 0.3},
            {"value": "{palette.mycolor}", "stop": 1},
        ],
    },
    "description": "whatever"
},

In css, this would translate to:

linear-gradient(180deg, #FABADA 0%, #F2E377 30%, #FFEEAA 100%)

😍 But I would avoid hex values. Only {palette.mycolor}. We don't need to open this to a custom colors ⚠️

aweell commented 7 months ago

But I would avoid hex values. Only {palette.mycolor}. We don't need to open this to a custom colors ⚠️

Agree with this, for two, three, low number of colors makes sense, but if we finally go with the easing hack having 12 or more variations of the same tone in the palette maybe is overkill?

amegias commented 7 months ago

But I would avoid hex values. Only {palette.mycolor}. We don't need to open this to a custom colors ⚠️

Agree with this, for two, three, low number of colors makes sense, but if we finally go with the easing hack maybe having 12 or more variations of the same tone in the palette maybe is overkill?

mmm... ok, good point. Then LGTM

alejandroruizponce commented 6 months ago

Agree with this, for two, three, low number of colors makes sense, but if we finally go with the easing hack having 12 or more variations of the same tone in the palette maybe is overkill?

According to the last comment, I have done the test on iOS following the example given above:

"backgroundBrand": {
    "type": "linear-gradient",
    "value": {
        "angle": 180,
        "colors": [
            {"value": "#FABADA", "stop": 0},
            {"value": "#F2E377", "stop": 0.3},
            {"value": "#FFEEAA}", "stop": 1},
        ],
    },
    "description": "whatever"
},

And I think it would be simpler if we get everything in hexadecimal, so that we don't have to distinguish between palette and hex values.

As we receive these values our way of drawing the gradient would be the following:

atabel commented 6 months ago

Agree with this, for two, three, low number of colors makes sense, but if we finally go with the easing hack having 12 or more variations of the same tone in the palette maybe is overkill?

According to the last comment, I have done the test on iOS following the example given above:

"backgroundBrand": {
    "type": "linear-gradient",
    "value": {
        "angle": 180,
        "colors": [
            {"value": "#FABADA", "stop": 0},
            {"value": "#F2E377", "stop": 0.3},
            {"value": "#FFEEAA}", "stop": 1},
        ],
    },
    "description": "whatever"
},

And I think it would be simpler if we get everything in hexadecimal, so that we don't have to distinguish between palette and hex values.

As we receive these values our way of drawing the gradient would be the following:

@alejandroruizponce, please, check the angle. 0 means from bottom to top; increasing values rotate clockwise from there. So 180 deg means from top to bottom https://mistica-web.vercel.app/playroom#?code=N4Igxg9gJgpiBcIA8UCWA3AOgOwAS4GcAXATwBsYBeYYHffAd1SiIAt5cAmABm4Bo69VjFQBzVkQ49%2Bg-ACMAhmADWogE4QArtijxZ9TCDKpsMBWoC06hWhjYiACgCMADm6xRfXAGIAYgEEAIX8AEX9cbgBSLz9OAFEAZgB2JNwEqJjfXzi4-3CnXkiASkMBPFwAXwqcAHoAPhwQPhA2GABbGAIEAG0QAFkIdFRicxAAXWamFlYu%2BG6EgDZuMYqgA

yceballost commented 6 months ago

And I think it would be simpler if we get everything in hexadecimal, so that we don't have to distinguish between palette and hex values.

We never include opacity in color palette, should we change this definition? I prefer to add opacity in constant to have more control and avoid creating tones of colors with different opacities

atabel commented 6 months ago

Do we agree on not using palette colors and always hardcode the colors in the gradient?

About transparency, what about this?:


"colors": [
    {"value": "#FABADA", "stop": 0},
    {"value": "#F2E377", "stop": 0.3},
    {"value": "rgba(255, 238, 170, 0.2)", "stop": 1},
],
alejandroruizponce commented 6 months ago

Agree with this, for two, three, low number of colors makes sense, but if we finally go with the easing hack having 12 or more variations of the same tone in the palette maybe is overkill?

According to the last comment, I have done the test on iOS following the example given above:

"backgroundBrand": {
    "type": "linear-gradient",
    "value": {
        "angle": 180,
        "colors": [
            {"value": "#FABADA", "stop": 0},
            {"value": "#F2E377", "stop": 0.3},
            {"value": "#FFEEAA}", "stop": 1},
        ],
    },
    "description": "whatever"
},

And I think it would be simpler if we get everything in hexadecimal, so that we don't have to distinguish between palette and hex values. As we receive these values our way of drawing the gradient would be the following:

@alejandroruizponce, please, check the angle. 0 means from bottom to top; increasing values rotate clockwise from there. So 180 deg means from top to bottom https://mistica-web.vercel.app/playroom#?code=N4Igxg9gJgpiBcIA8UCWA3AOgOwAS4GcAXATwBsYBeYYHffAd1SiIAt5cAmABm4Bo69VjFQBzVkQ49%2Bg-ACMAhmADWogE4QArtijxZ9TCDKpsMBWoC06hWhjYiACgCMADm6xRfXAGIAYgEEAIX8AEX9cbgBSLz9OAFEAZgB2JNwEqJjfXzi4-3CnXkiASkMBPFwAXwqcAHoAPhwQPhA2GABbGAIEAG0QAFkIdFRicxAAXWamFlYu%2BG6EgDZuMYqgA

You are right, it seems that our way of interpreting angles in iOS is different from CSS. We start from the top left. I have fixed our logic so that it interprets the angle the same as in CSS, from top to bottom:

jeprubio commented 6 months ago

Does this mean that any of the colours we have in mistica theme could be a gradient instead of a colour? Shouldn't this be a component with a gradient background and nothing else?

jeprubio commented 6 months ago

Talked to the team, the ones that have answered no one thinks the app can receive from the current tokens colours or gradients indistinctly and still not crash. Current colours are in many places in xml, if what's received in that current tokens in that files is not a colour the app is going to crash.

jeprubio commented 6 months ago

In compose, by usiung the gist: https://gist.github.com/jeprubio/6be0d2406b1aad41912c4701155d593f

and applying its gradientBackground modifier:

Box(
    modifier = Modifier
        .size(200.dp)
        .gradientBackground(
            0f to Color(0xFFFABADA),
            0.3f to Color(0xFFF2E377),
            1.0f to Color(0xFFFFEEAA),
            angle = 180f
        )
)

I get the following result: gradient

but still the previous problems are there. (check our confluence: https://confluence.tid.es/pages/viewpage.action?pageId=269614601)