Theme-ui: [idea] Quick-and-dirty shorthand parsing idea

Created on 18 Jun 2019  路  2Comments  路  Source: system-ui/theme-ui

Right now, there's no support for shorthand properties. This means that I can't set something like this:

{
  Container: {
   border: '1px solid primary'
  }
}

One idea for allowing this could be to split the shorthand into string tokens using .split, then look for tokens and replace.

// assumes the value is border shorthand: '1px solid primary'
border.split(' ').map(replaceThemeUITokensWithValues).join(' ')

The edge case here would be comma-separated values (e.g. multiple backgrounds):

{
  Container: {
    background: 'primary, rgba(0, 0, 0, 0.75)'
  }
}

This could be worked around with regex 馃槺 (e.g. /([,\s]*)(\w+)([,\s]*)/) to capture non-word characters and drop them back in:

const handleNonWordCharacters = str => {
  const [_, pre, maybeToken, post] = str.match(/([,\s]*)(\w+)([,\s]*)/);

  return pre + replaceThemeUITokensWithValues(maybeToken) + post;
}

There are probably a large number of dragons to consider with this approach, but if it's limited to only a few shorthand properties (e.g. border, background) maybe it's manageable?

enhancement help wanted

Most helpful comment

Would love to support this sort of functionality! Generally, I'm a little bit skeptical of attempting to parse string values in CSS, but I think this proposal has some legs. To start this with a smaller scope, I'd suggest starting with only handling CSS properties that include colors, so that the logic for using keys from the theme.colors object to replace strings in places like border and boxShadow can be vetted before attempting other theme keys. I also suspect this would be the biggest win in the short term.

Other things to consider:

  • Color objects can be nested, so this should support values like blue.dark.2
  • A decent amount of work here would probably be adding some test fixtures to make sure this works with a lot of edge cases
  • The relevant source code is mostly in @styled-system/css at the moment

Related #75

All 2 comments

Would love to support this sort of functionality! Generally, I'm a little bit skeptical of attempting to parse string values in CSS, but I think this proposal has some legs. To start this with a smaller scope, I'd suggest starting with only handling CSS properties that include colors, so that the logic for using keys from the theme.colors object to replace strings in places like border and boxShadow can be vetted before attempting other theme keys. I also suspect this would be the biggest win in the short term.

Other things to consider:

  • Color objects can be nested, so this should support values like blue.dark.2
  • A decent amount of work here would probably be adding some test fixtures to make sure this works with a lot of edge cases
  • The relevant source code is mostly in @styled-system/css at the moment

Related #75

Thanks so much for the idea here. This feature would be awesome to have, but introduces a lot of complexity to the parsing & a lot of edge cases for various properties, which will almost certainly slow down Theme UI further. For now, we鈥檙e going to stick to encouraging functional values (e.g. (theme) => \3px solid ${theme.colors.blue}``) & keep this on the back burner for a potential Babel plugin.

Was this page helpful?
0 / 5 - 0 ratings