Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better Composition #179

Closed
emmatown opened this issue Jul 25, 2017 · 4 comments · Fixed by #213
Closed

Better Composition #179

emmatown opened this issue Jul 25, 2017 · 4 comments · Fixed by #213

Comments

@emmatown
Copy link
Member

Because of #154 we can make composition way more powerful. We should be able to support interpolations anywhere.

This is what I'm thinking should be possible

const flexCenter = css`
  display: flex;
  justify-content: center;
  align-items: center;
`

const CenteredComponent = styled.div`
  display: block;
  ${flexCenter}
`

In this example display: flex; should take priority over display: block; since the interpolation is after display: block;.

This should be possible since we can split the output object at each interpolation. We will likely have to use a custom version of postcss-js's objectify to do this. We'll also have to make postcss think interpolations are at rules so they be parsed.

@lukeed
Copy link
Contributor

lukeed commented Jul 30, 2017

I've been checked out for a bit, but aren't these returned as objects? If so, then you can recursively expand/assign the object into a result. Nested objects will overwrite any matching, existing keys.

@tkh44
Copy link
Member

tkh44 commented Jul 30, 2017

@lukeed They return strings. This problem is a bit more nuanced than that, but what you describe is where we are on the path to currently. The first step was to get objects working.

@lukeed
Copy link
Contributor

lukeed commented Jul 30, 2017

Gotcha 👍

This is likely your path already, but just in case... in my mind, I see this happening:

const flexCenter = {
  display: 'flex',
  'justify-content': 'center',
  'align-items': 'center'
};

const centeredComponent = [{
  display: 'block',
  'text-align': 'center'
}, flexCenter];
//=> `compose` = [styles].push(object);

function assign(tar) {
  var k, src, i=1, len=arguments.length;
  for (; i < len; i++) {
    src = arguments[i];
    for (k in src) {
      tar[k] = src[k];
    }
  }
  return tar;
}

function compile(val) {
  return Array.isArray(val) ? assign.apply(null, val) : val;
}

console.log( compile(flexCenter) );
//=> { display: 'flex',
//=>   'justify-content': 'center',
//=>   'align-items': 'center' }

console.log( compile(centeredComponent) );
//=> { display: 'flex',
//=>   'text-align': 'center',
//=>   'justify-content': 'center',
//=>   'align-items': 'center' }

Of course, could also just use Object.assign if don't care about IE.

Once you have these outputs, then I would convert the keys into the appropriate property names.

@tkh44
Copy link
Member

tkh44 commented Jul 31, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants