system-ui / theme-ui

Build consistent, themeable React apps based on constraint-based design principles
https://theme-ui.com
MIT License
5.28k stars 676 forks source link

[@theme-ui/color] Allow multiple color manipulation methods #1984

Open aaronadamsCA opened 2 years ago

aaronadamsCA commented 2 years ago

Is your feature request related to a problem? Please describe. I'd like to be able to easily set both lightness and alpha values for the same color value using the @theme-ui/color utilities.

Describe the solution you'd like bg: alpha(lightness("muted", 0.95), 0.95) or similar.

Describe alternatives you've considered Not sure. Current TS error:

Argument of type '(t: Theme) => string' is not assignable to parameter of type 'Color | Color[] | NestedScaleDict<Color> | undefined'.
  Type '(t: Theme) => string' is not assignable to type 'NestedScaleDict<Color>'.
    Index signature for type 'string' is missing in type '(t: Theme) => string'. ts(2345)

There might be a way around it, but I can't figure it out right now.

Additional context Selecting both lightness and alpha is important for building themes with adaptive colour schemes.

aaronadamsCA commented 2 years ago

I did find a syntax that works, but it's not the nicest: bg: (t) => alpha(lightness("muted", 0.95)(t), 0.95)(t)

lachlanjc commented 2 years ago

Interesting, thanks for the well-written issue. To clarify, is this an issue only with our types, or with the functions themselves as well?

hasparus commented 2 years ago

@lachlanjc I’d say this is a feature request for new function.

I’d probably try to build on top of getColor from @theme-ui/color and hsla from polished.

aaronadamsCA commented 2 years ago

Yep, I filed this as a feature request. It may just be a limitation of the chosen syntax, but I'm increasingly finding I'd like to have easy control of both the L and A values in an HSLA value.

It's more or less the way Material You works in Android 12, for instance. It's a very powerful way to accept any input colour and make it appropriate to a given UI context.

Maybe a chained syntax would be preferable, like getColor("muted").lightness(0.95).alpha(0.95).