segmentio / evergreen

🌲 Evergreen React UI Framework by Segment
https://evergreen.segment.com
MIT License
12.38k stars 830 forks source link

Not being able to theme shadows #1520

Closed codeheart09 closed 1 year ago

codeheart09 commented 1 year ago

So, I'm trying to customize the shadows property of the theme. For that I created the object to merge with the defaultTheme.

const evergreen = {
  shadows: [
    '0 0 1px rgba(67, 90, 111, 0.3)',
    '0 0 1px rgba(67, 90, 111, 0.3), 0 2px 4px -2px rgba(67, 90, 111, 0.47)',
    '0 0 1px rgba(67, 90, 111, 0.3), 0 5px 8px -4px rgba(67, 90, 111, 0.47)',
    '0 0 1px rgba(67, 90, 111, 0.3), 0 8px 10px -4px rgba(67, 90, 111, 0.47)',
    '0 0 1px rgba(67, 90, 111, 0.3), 0 16px 24px -8px rgba(67, 90, 111, 0.47)'
  ]
}

But when I apply this to the ThemeProvider I get:

TS2345: Argument of type '{ shadows: string[]; }' is not assignable to parameter of type 'Partial<Theme<Components>>'.
  Types of property 'shadows' are incompatible.
    Type 'string[]' is not assignable to type 'string[] & { focusRing: string; }'.
      Property 'focusRing' is missing in type 'string[]' but required in type '{ focusRing: string; }'.

I'm not sure how can I merge a string array with an object. This may be a silly thing, but this is indeed the expected goal? How would I do that?

Thanks for any help.

brandongregoryscott commented 1 year ago

Hey @codeheart09 - it is indeed a strange type (and probably something we should move away from / have a separate token for), but this is how it's currently implemented (in JS): https://github.com/segmentio/evergreen/blob/master/src/themes/default/tokens/shadows.js#L10-L18

Unfortunately I think you'll need to cast the shadows array, regardless of whether you want to override the focusRing value:

import { Theme } from "evergreen-ui";

const shadows: Theme["shadows"] = [...] as Theme["shadows"]

Once it has been cast, you should be able to assign the focusRing property as well..

shadows.focusRing = "red";