Repository: tkh44/emotion
Pull request #95 (2017-07-05 09:12:54)

Support composes values based on props and components as child selectors in Vue
<!--
Thanks for your interest in the project. I appreciate bugs filed and PRs submitted!

Please make sure that you are familiar with and follow the Code of Conduct for
this project (found in the CODE_OF_CONDUCT.md file).

Also, please make sure you're familiar with and follow the instructions in the
contributing guidelines (found in the CONTRIBUTING.md file).

If you're new to contributing to open source projects, you might find this free
video course helpful: http://kcd.im/pull-request

Please fill out the information below to expedite the review and (hopefully)
merge of your pull request!
-->

<!-- What changes are being made? (What feature/bug is being fixed here?) -->
**What**:

<!-- Why are these changes necessary? -->
**Why**:

<!-- How were these changes implemented? -->
**How**:

<!-- Have you done all of these things?  -->
**Checklist**:
<!-- add "N/A" to the end of each line that's irrelevant to your changes -->
<!-- to check an item, place an "x" in the box like so: "- [x] Documentation" -->
- [ ] Documentation
- [x] Tests
- [x] Code complete

<!-- feel free to add additional comments -->


codecov-io: # [Codecov](https://codecov.io/gh/tkh44/emotion/pull/95?src=pr&el=h1) Report
> Merging [#95](https://codecov.io/gh/tkh44/emotion/pull/95?src=pr&el=desc) into [master](https://codecov.io/gh/tkh44/emotion/commit/e5cbb467fe0ca530d510f4608b7e1c32a95fbf81?src=pr&el=desc) will **not change** coverage.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/tkh44/emotion/pull/95/graphs/tree.svg?token=B1bWuYNE2t&width=650&height=150&src=pr)](https://codecov.io/gh/tkh44/emotion/pull/95?src=pr&el=tree)

```diff
@@           Coverage Diff           @@
##           master      #95   +/-   ##
=======================================
  Coverage   88.38%   88.38%           
=======================================
  Files          15       15           
  Lines         568      568           
  Branches      119      119           
=======================================
  Hits          502      502           
  Misses         53       53           
  Partials       13       13
```


| [Impacted Files](https://codecov.io/gh/tkh44/emotion/pull/95?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [src/vue.js](https://codecov.io/gh/tkh44/emotion/pull/95?src=pr&el=tree#diff-c3JjL3Z1ZS5qcw==) | `100% <100%> (ø)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/tkh44/emotion/pull/95?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/tkh44/emotion/pull/95?src=pr&el=footer). Last update [e5cbb46...79c3aa8](https://codecov.io/gh/tkh44/emotion/pull/95?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/src/vue.js b/src/vue.js
index ce35e9c6..298813cb 100644
--- a/src/vue.js
+++ b/src/vue.js
@@ -2,11 +2,13 @@ import { css as magic } from './index'
 
 const styled = (tag, cls, vars = [], content) => {
   return {
+    cls: '.' + cls,
     functional: true,
     render (h, context) {
+      const getValue = v => (v && typeof v === 'function' ? v(context.props) : v.cls || v)
       const className = magic(
-        cls,
-        vars.map(v => (v && typeof v === 'function' ? v(context.props) : v)),
+        cls.map(getValue),
+        vars.map(getValue),
         content
       )
       return h(


Test patch:
diff --git a/test/__snapshots__/vue.test.js.snap b/test/__snapshots__/vue.test.js.snap
index 8efc97ba..ae2d8ad0 100644
--- a/test/__snapshots__/vue.test.js.snap
+++ b/test/__snapshots__/vue.test.js.snap
@@ -6,12 +6,24 @@ exports[`vue styled based on props 1`] = `
     "
 `;
 
+exports[`vue styled based on props composes 1`] = `
+"
+      <div id=\\"app\\"><div thing=\\"true\\" class=\\"css-basedOnPropsComposes-17rcs0o-12iwoui css-basedOnPropsComposes-17rcs0o some-special-class\\"></div></div>
+    "
+`;
+
 exports[`vue styled basic 1`] = `
 "
       <div id=\\"app\\"><div class=\\"css-StyledComponent-1brvt4i-ulwf5d css-StyledComponent-1brvt4i\\"></div></div>
     "
 `;
 
+exports[`vue styled child selector 1`] = `
+"
+      <div id=\\"app\\"><main class=\\"css-ChildSelector-13pvedz-1e7xvxz css-ChildSelector-13pvedz\\"><div class=\\"css-StyledComponent-1brvt4i-ulwf5d css-StyledComponent-1brvt4i\\">wow</div></main></div>
+    "
+`;
+
 exports[`vue styled creates the correct styles 1`] = `
 ".css-StyledComponent-1brvt4i-ulwf5d { display: -webkit-box; display: -moz-box; display: -ms-flexbox; display: -webkit-flex; display: flex;
   -webkit-justify-content: center;
@@ -22,8 +34,8 @@ exports[`vue styled creates the correct styles 1`] = `
   -ms-flex-align: center;
   -webkit-box-align: center;
   align-items: center;
-  position: inherit; }.css-BasedOnProps-csm9t8-1qo3zsu { font-weight: bold; }.css-NonHtmlComponent-15287sz-1wq2ikh { background-color: purple;
-  color: green; }"
+  position: inherit; }.css-BasedOnProps-csm9t8-1qo3zsu { font-weight: bold; }.css-basedOnPropsComposes-17rcs0o-12iwoui { }.css-NonHtmlComponent-15287sz-1wq2ikh { background-color: purple;
+  color: green; }.css-ChildSelector-13pvedz-1e7xvxz { color: yellow; }.css-ChildSelector-13pvedz-1e7xvxz .css-StyledComponent-1brvt4i { display: none; }"
 `;
 
 exports[`vue styled custom external component 1`] = `
diff --git a/test/vue.test.js b/test/vue.test.js
index 1eedee29..e88ad934 100644
--- a/test/vue.test.js
+++ b/test/vue.test.js
@@ -31,9 +31,22 @@ const NonHtmlComponent = styled(baseComponent)`
   color: green;
 `
 
+const basedOnPropsComposes = styled.div`
+  composes: ${(props) => props.thing ? 'some-special-class' : ''}
+`
+
+const ChildSelector = styled.main`
+  color: yellow;
+  ${StyledComponent} {
+    display: none;
+  }
+`
+
 Vue.component('styled-component', StyledComponent)
 Vue.component('based-on-props', BasedOnProps)
+Vue.component('based-on-props-composes', basedOnPropsComposes)
 Vue.component('non-html-component', NonHtmlComponent)
+Vue.component('child-selector', ChildSelector)
 
 describe('vue styled', () => {
   test('basic', async () => {
@@ -101,6 +114,19 @@ describe('vue styled', () => {
     await Vue.nextTick(() => {})
     expect(document.body.innerHTML).toMatchSnapshot()
   })
+  test('based on props composes', async () => {
+    document.body.innerHTML = `
+      <div id="app">
+          <based-on-props-composes thing="true"></based-on-props-composes>
+      </div>
+    `
+    new Vue({
+      el: '#app'
+    })
+
+    await Vue.nextTick(() => {})
+    expect(document.body.innerHTML).toMatchSnapshot()
+  })
   test('custom external component', async () => {
     document.body.innerHTML = `
       <div id="app">
@@ -114,6 +140,19 @@ describe('vue styled', () => {
     await Vue.nextTick(() => {})
     expect(document.body.innerHTML).toMatchSnapshot()
   })
+  test('child selector', async () => {
+    document.body.innerHTML = `
+      <div id="app">
+          <child-selector><styled-component>wow</styled-component></child-selector>
+      </div>
+    `
+    new Vue({
+      el: '#app'
+    })
+
+    await Vue.nextTick(() => {})
+    expect(document.body.innerHTML).toMatchSnapshot()
+  })
   test('creates the correct styles', () => {
     expect(
       sheet.tags.map(tag => tag.textContent || '').join('')