Emotion: RFC: Replace array value fallbacks with array value concatenation

Created on 6 Feb 2020  路  9Comments  路  Source: emotion-js/emotion

The problem

Currently, in emotion when an array value is encountered the values are treated as a primary value with fallback values that are duplicated for the same property.

Example:

<div
  css={{
    backgroundColor: ['hsla(134, 96%, 68%, 1.0)', 'rgb(95, 252, 132, 1)']
  }}
/>

image

This is a little known feature that is, anecdotally, rarely used. Further, I don't believe it is as useful as it once would have been due to the current browser css support landscape.

The current parsing behavior for array values prevents the syntax from being used for anything else.

Proposed solution

One of the pain points while leading teams using object styles and using them extensively myself is having to use string concatenation/template literals and/or long hand for properties that support shorthand.

I would like to allow values to accept arrays which would get concatenated by emotion in a somewhat intelligent fashion.

Some examples

padding & margin

_potential to automatically append px_

All three of these would result in the same padding values

<div
  css={{
    padding: `${space[1]}px ${space[3]}px ${space[2]}px ${space[2]}px`
  }}
/>

<div
  css={{
    paddingTop: space[1],
    paddingRight: space[3],
    paddingBottom: space[2],
    paddingLeft: space[2]
  }}
/>

<div
  css={{
    padding: [space[1], space[3], space[2], space[2]] // <-- new use for array
  }}
/>

border

Properties such as border that have multiple value types would get concatenated.

_could detect number types and append px_

<div
  css={{
    border: `1px solid ${theme.colors.blue}`
  }}
/>

<div
  css={{
    border: [`1px solid`, theme.colors.border]
  }}
/>

<div
  css={{
    border: [1, `solid`, theme.colors.blue] // Numbers get px added automatically (?)
  }}
/>

Alternative solutions

An alternative would be to simply concatenate the values or to remove the fallback array syntax altogether and let the behavior be defined by the user if/when we get some sort of plugin system in the future.

EDIT

After thinking about this for some time I think the best solution would be to just remove the fallback value so that these types of values can be used for any situation later on. It could be used for the solution above or media query values such as those used in styled-system or facepaint.

Additional context

As more users leverage the power of themes I think we should make it as easy as possible to work with them while using object styles. I'm excited to hear everyone's thoughts on this and their alternative idea/solutions.

discussion feature request needs triage

Most helpful comment

Really like this idea! One other use-case that I find pretty monotonous right now is writing transforms. Using the array syntax, this could work like this:

transform: [['rotate', '40deg'], ['translateY', theme.space.large + theme.space.base]]

All 9 comments

Really like this idea! One other use-case that I find pretty monotonous right now is writing transforms. Using the array syntax, this could work like this:

transform: [['rotate', '40deg'], ['translateY', theme.space.large + theme.space.base]]

I don't personally use array values, but wondering if a plugin system could allow this functionality and provide better support for things like style props or however people want to resolve values?

After thinking about this for some time I think the best solution would be to just remove the fallback value so that these types of values can be used for any situation later on. It could be used for the solution above or media query values such as those used in styled-system or facepaint.

@mitchellhamilton WDYT? I quite agree that we don't need the current feature of fallback values, i doubt many users are using it - OTOH it's hard~ to achieve the same result without this feature

The main reason for doing this is so that we can override this with some kind of as yet undefined plugin system right?

My main question is: why couldn't someone override this syntax with the as yet undefined plugin system or @tkh44 are you proposing supporting some of this syntax natively in the future?

My thinking is that it would allow this powerful syntax to be used in the future for whatever we decide. My reasoning for removing fallbacks at this point is because it times perfectly with a major version change.

@Andarist why is it hard to achieve? Couldn't it be done manually with multiple properties by hand?

<div
  css={{
    backgroundColor: 'hsla(134, 96%, 68%, 1.0)',
    backgroundColor: 'rgb(95, 252, 132, 1)'
  }}
/>

The last defined property with the same key wins, doesnt it? 馃槈

Oh I feel silly. I need more coffee it looks like. Maybe we should close this now that you bring this simple aspect up.

Closing this as it's probably not something we'd like to change right now. Different approaches can always be considered for new major versions

Was this page helpful?
0 / 5 - 0 ratings