Repository: tkh44/emotion
Pull request #225 (2017-08-02 17:52:09)

#212 - remove theming
Putting this up early to get more eyes on it.

<!-- 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/225?src=pr&el=h1) Report
> Merging [#225](https://codecov.io/gh/tkh44/emotion/pull/225?src=pr&el=desc) into [master](https://codecov.io/gh/tkh44/emotion/commit/57af90cf2fcb23d52a2e77d098a880edd8be71b6?src=pr&el=desc) will **increase** coverage by `0.11%`.
> The diff coverage is `100%`.

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

```diff
@@            Coverage Diff            @@
##           master    #225      +/-   ##
=========================================
+ Coverage   90.39%   90.5%   +0.11%     
=========================================
  Files          22      20       -2     
  Lines         979    1022      +43     
  Branches      265     295      +30     
=========================================
+ Hits          885     925      +40     
- Misses         76      77       +1     
- Partials       18      20       +2
```


| [Impacted Files](https://codecov.io/gh/tkh44/emotion/pull/225?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [src/react/index.js](https://codecov.io/gh/tkh44/emotion/pull/225?src=pr&el=tree#diff-c3JjL3JlYWN0L2luZGV4Lmpz) | `100% <100%> (ø)` | :arrow_up: |
| [src/index.js](https://codecov.io/gh/tkh44/emotion/pull/225?src=pr&el=tree#diff-c3JjL2luZGV4Lmpz) | `94.2% <0%> (+0.11%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/tkh44/emotion/pull/225?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/225?src=pr&el=footer). Last update [57af90c...32099c1](https://codecov.io/gh/tkh44/emotion/pull/225?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/src/react/constants.js b/src/react/constants.js
deleted file mode 100644
index 0652cd14..00000000
--- a/src/react/constants.js
+++ /dev/null
@@ -1,1 +0,0 @@
-export const CHANNEL = '__emotion__'
diff --git a/src/react/index.js b/src/react/index.js
index 2b58d80b..a185a7c5 100644
--- a/src/react/index.js
+++ b/src/react/index.js
@@ -1,8 +1,6 @@
-import { Component, createElement as h } from 'react'
-import PropTypes from 'prop-types'
+import { createElement as h } from 'react'
 import { css } from '../index'
 import { map, omit, reduce, assign } from '../utils'
-import { CHANNEL } from './constants'
 
 export {
   flush,
@@ -25,98 +23,64 @@ export default function (tag, cls, objs, vars = [], content) {
 
   const componentTag = tag.displayName || tag.name || 'Component'
 
-  class Styled extends Component {
-    state = {
-      theme: {}
-    }
-
-    componentWillMount () {
-      if (this.context[CHANNEL]) {
-        this.setState({ theme: this.context[CHANNEL].getState() })
-      }
-    }
-
-    componentDidMount () {
-      if (this.context[CHANNEL]) {
-        this.unsubscribe = this.context[CHANNEL].subscribe(this.setTheme)
-      }
-    }
-
-    componentWillUnmount () {
-      if (typeof this.unsubscribe === 'function') {
-        this.unsubscribe()
-      }
-    }
-
-    render () {
-      const { props, state, context } = this
-      const mergedProps = assign({}, props, {
-        theme: state.theme
-      })
-
-      const getValue = v => {
-        if (v && typeof v === 'function') {
-          if (v.__emotion_class) {
-            return `& .${v.__emotion_class}`
-          }
-          return v(mergedProps, context)
+  function Styled (props, context) {
+    const getValue = v => {
+      if (v && typeof v === 'function') {
+        if (v.__emotion_class) {
+          return `& .${v.__emotion_class}`
         }
-
-        return v
+        return v(props, context)
       }
-      let localTag = tag
-
-      let finalObjs = []
 
-      if (tag.__emotion_spec) {
-        push(
-          finalObjs,
-          reduce(
-            tag.__emotion_spec,
-            (accum, spec) => {
-              push(accum, spec.objs)
-              if (spec.content) {
-                push(accum, spec.content.apply(null, map(spec.vars, getValue)))
-              }
-              return accum
-            },
-            []
-          )
+      return v
+    }
+    let localTag = tag
+
+    let finalObjs = []
+
+    if (tag.__emotion_spec) {
+      push(
+        finalObjs,
+        reduce(
+          tag.__emotion_spec,
+          (accum, spec) => {
+            push(accum, spec.objs)
+            if (spec.content) {
+              push(accum, spec.content.apply(null, map(spec.vars, getValue)))
+            }
+            push(accum, [spec.cls])
+            return accum
+          },
+          []
         )
-        localTag = tag.__emotion_spec[0].tag
-      }
-
-      push(finalObjs, objs)
-
-      push(finalObjs, [cls])
+      )
+      localTag = tag.__emotion_spec[0].tag
+    }
 
-      if (content) {
-        push(finalObjs, content.apply(null, map(vars, getValue)))
-      }
+    push(finalObjs, objs)
 
-      if (mergedProps.className) {
-        push(finalObjs, mergedProps.className.split(' '))
-      }
+    push(finalObjs, [cls])
 
-      const className = css(map(finalObjs, getValue))
+    if (content) {
+      push(finalObjs, content.apply(null, map(vars, getValue)))
+    }
 
-      return h(
-        localTag,
-        omit(
-          assign({}, mergedProps, {
-            ref: mergedProps.innerRef,
-            className
-          }),
-          ['innerRef', 'theme']
-        )
-      )
+    if (props.className) {
+      push(finalObjs, props.className.split(' '))
     }
 
-    setTheme = theme => this.setState({ theme })
-  }
+    const className = css(map(finalObjs, getValue))
 
-  Styled.contextTypes = {
-    [CHANNEL]: PropTypes.object
+    return h(
+      localTag,
+      omit(
+        assign({}, props, {
+          ref: props.innerRef,
+          className
+        }),
+        ['innerRef', 'theme']
+      )
+    )
   }
 
   Styled.displayName = `styled(${componentTag})`
@@ -124,7 +88,8 @@ export default function (tag, cls, objs, vars = [], content) {
     vars,
     content,
     objs,
-    tag
+    tag,
+    cls
   }
   Styled.__emotion_spec = tag.__emotion_spec
     ? tag.__emotion_spec.concat(spec)
diff --git a/src/react/theming.js b/src/react/theming.js
deleted file mode 100644
index a44b8679..00000000
--- a/src/react/theming.js
+++ /dev/null
@@ -1,6 +0,0 @@
-import { createTheming } from 'theming'
-import { CHANNEL } from './constants'
-
-const theming = createTheming(CHANNEL)
-const { withTheme, ThemeProvider } = theming
-export { CHANNEL, withTheme, ThemeProvider }


Test patch:
diff --git a/test/__snapshots__/react.test.js.snap b/test/__snapshots__/react.test.js.snap
index 63b42115..ff9b0058 100644
--- a/test/__snapshots__/react.test.js.snap
+++ b/test/__snapshots__/react.test.js.snap
@@ -57,13 +57,21 @@ exports[`styled change theme 1`] = `
       }
     }
   >
-    <styled(Component)>
-      <div
-        className="glamor-0 glamor-1"
+    <WithTheme(styled(Component))>
+      <styled(Component)
+        theme={
+          Object {
+            "primary": "green",
+          }
+        }
       >
-        this will be green then pink
-      </div>
-    </styled(Component)>
+        <div
+          className="glamor-0 glamor-1"
+        >
+          this will be green then pink
+        </div>
+      </styled(Component)>
+    </WithTheme(styled(Component))>
   </ThemeProvider>
 </TestComponent>
 `;
@@ -88,13 +96,21 @@ exports[`styled change theme 2`] = `
       }
     }
   >
-    <styled(Component)>
-      <div
-        className="glamor-0 glamor-1"
+    <WithTheme(styled(Component))>
+      <styled(Component)
+        theme={
+          Object {
+            "primary": "pink",
+          }
+        }
       >
-        this will be green then pink
-      </div>
-    </styled(Component)>
+        <div
+          className="glamor-0 glamor-1"
+        >
+          this will be green then pink
+        </div>
+      </styled(Component)>
+    </WithTheme(styled(Component))>
   </ThemeProvider>
 </TestComponent>
 `;
@@ -177,13 +193,13 @@ exports[`styled component as selector function interpolation 1`] = `
 `;
 
 exports[`styled composes 1`] = `
-.glamor-1 {
+.glamor-2 {
   color: blue;
   font-size: 32px;
 }
 
 <h1
-  className="glamor-0 legacy__class glamor-1"
+  className="glamor-0 glamor-1 legacy__class glamor-2"
   scale={2}
 >
   hello world
@@ -216,7 +232,7 @@ exports[`styled composes based on props 2`] = `
 `;
 
 exports[`styled composes with objects 1`] = `
-.glamor-1 {
+.glamor-2 {
   color: #333;
   font-size: 32px;
   height: 64px;
@@ -227,13 +243,13 @@ exports[`styled composes with objects 1`] = `
     only screen and (-o-min-device-pixel-ratio: 1.5/1),
     only screen and (min-resolution: 144dpi),
     only screen and (min-resolution: 1.5dppx) {
-  .glamor-1 {
+  .glamor-2 {
     font-size: 1.4323121856191332em;
   }
 }
 
 <h1
-  className="glamor-0 legacy__class glamor-1"
+  className="glamor-0 glamor-1 legacy__class glamor-2"
   scale={2}
 >
   hello world
@@ -241,7 +257,7 @@ exports[`styled composes with objects 1`] = `
 `;
 
 exports[`styled composing components 1`] = `
-.glamor-1 {
+.glamor-3 {
   color: green;
   display: -webkit-box;
   display: -ms-flexbox;
@@ -252,31 +268,31 @@ exports[`styled composing components 1`] = `
 }
 
 <button
-  className="glamor-0 glamor-1"
+  className="glamor-0 glamor-1 glamor-2 glamor-3"
 >
   hello world
 </button>
 `;
 
 exports[`styled composition 1`] = `
-.glamor-1 {
+.glamor-2 {
   font-size: 13.333333333333334px;
 }
 
 <h1
-  className="glamor-0 legacy__class glamor-1"
+  className="glamor-0 glamor-1 legacy__class glamor-2"
 >
   hello world
 </h1>
 `;
 
 exports[`styled function in expression 1`] = `
-.glamor-1 {
+.glamor-2 {
   font-size: 40px;
 }
 
 <h1
-  className="glamor-0 legacy__class glamor-1"
+  className="glamor-0 glamor-1 legacy__class glamor-2"
   scale={2}
 >
   hello world
@@ -297,6 +313,7 @@ exports[`styled handles more than 10 dynamic properties 1`] = `
   z-index: 100;
   font-size: 18px;
   text-align: center;
+  border-left: blue;
 }
 
 <h1
@@ -307,7 +324,7 @@ exports[`styled handles more than 10 dynamic properties 1`] = `
 `;
 
 exports[`styled higher order component 1`] = `
-.glamor-1 {
+.glamor-2 {
   font-size: 20px;
   background-color: '#343a40';
   -webkit-box-orient: vertical;
@@ -317,7 +334,7 @@ exports[`styled higher order component 1`] = `
 }
 
 <div
-  className="glamor-0 glamor-1"
+  className="glamor-0 glamor-1 glamor-2"
 />
 `;
 
@@ -520,7 +537,7 @@ exports[`styled random object expression 1`] = `
 `;
 
 exports[`styled themes 1`] = `
-.glamor-1 {
+.glamor-3 {
   background-color: #ffd43b;
   color: #8c81d8;
   height: 64px;
@@ -528,7 +545,7 @@ exports[`styled themes 1`] = `
 }
 
 <span
-  className="glamor-0 glamor-1"
+  className="glamor-0 glamor-1 glamor-2 glamor-3"
   scale={2}
 >
   hello world
diff --git a/test/macro/__snapshots__/react.test.js.snap b/test/macro/__snapshots__/react.test.js.snap
index ab0614e3..d3817ab6 100644
--- a/test/macro/__snapshots__/react.test.js.snap
+++ b/test/macro/__snapshots__/react.test.js.snap
@@ -61,14 +61,14 @@ exports[`styled component as selector 1`] = `
 `;
 
 exports[`styled composes 1`] = `
-.glamor-1 {
+.glamor-2 {
   color: blue;
   height: 64px;
   font-size: 32px;
 }
 
 <h1
-  className="glamor-0 glamor-1"
+  className="glamor-0 glamor-1 glamor-2"
   scale={2}
 >
   hello world
@@ -101,7 +101,7 @@ exports[`styled composes based on props 2`] = `
 `;
 
 exports[`styled composes with objects 1`] = `
-.glamor-1 {
+.glamor-2 {
   color: #333;
   font-size: 1.333em;
   height: 64px;
@@ -113,13 +113,13 @@ exports[`styled composes with objects 1`] = `
     only screen and (-o-min-device-pixel-ratio: 1.5/1),
     only screen and (min-resolution: 144dpi),
     only screen and (min-resolution: 1.5dppx) {
-  .glamor-1 {
+  .glamor-2 {
     font-size: 1.4323121856191332em;
   }
 }
 
 <h1
-  className="glamor-0 glamor-1"
+  className="glamor-0 glamor-1 glamor-2"
   scale={2}
 >
   hello world
@@ -127,24 +127,24 @@ exports[`styled composes with objects 1`] = `
 `;
 
 exports[`styled composition 1`] = `
-.glamor-1 {
+.glamor-2 {
   font-size: 13.333333333333334px;
 }
 
 <h1
-  className="glamor-0 glamor-1"
+  className="glamor-0 glamor-1 glamor-2"
 >
   hello world
 </h1>
 `;
 
 exports[`styled function in expression 1`] = `
-.glamor-1 {
+.glamor-2 {
   font-size: 40px;
 }
 
 <h1
-  className="glamor-0 glamor-1"
+  className="glamor-0 glamor-1 glamor-2"
   scale={2}
 >
   hello world
@@ -152,7 +152,7 @@ exports[`styled function in expression 1`] = `
 `;
 
 exports[`styled higher order component 1`] = `
-.glamor-1 {
+.glamor-2 {
   font-size: 20px;
   background-color: '#343a40';
   -webkit-box-orient: vertical;
@@ -162,7 +162,7 @@ exports[`styled higher order component 1`] = `
 }
 
 <div
-  className="glamor-0 glamor-1"
+  className="glamor-0 glamor-1 glamor-2"
 />
 `;
 
@@ -218,7 +218,7 @@ exports[`styled objects 1`] = `
 `;
 
 exports[`styled themes 1`] = `
-.glamor-1 {
+.glamor-3 {
   background-color: #ffd43b;
   color: #8c81d8;
   height: 64px;
@@ -226,7 +226,7 @@ exports[`styled themes 1`] = `
 }
 
 <span
-  className="glamor-0 glamor-1"
+  className="glamor-0 glamor-1 glamor-2 glamor-3"
   scale={2}
 >
   hello world
diff --git a/test/macro/react.test.js b/test/macro/react.test.js
index b8e4f84f..c72ba6c7 100644
--- a/test/macro/react.test.js
+++ b/test/macro/react.test.js
@@ -4,7 +4,7 @@ import renderer from 'react-test-renderer'
 import serializer from 'jest-glamor-react'
 import { css, sheet } from '../../src/macro'
 import styled from '../../src/react/macro'
-import { ThemeProvider } from '../../src/react/theming'
+import { ThemeProvider, withTheme } from 'theming'
 
 import { lighten, hiDPI, modularScale } from 'polished'
 
@@ -189,15 +189,15 @@ describe('styled', () => {
       height: 64px;
     `
 
-    const Heading = styled('span')`
+    const Heading = withTheme(styled('span')`
       background-color: ${p => p.theme.gold};
-    `
+    `)
 
-    const H1 = styled(Heading)`
+    const H1 = withTheme(styled(Heading)`
       composes: ${cssB};
       font-size: ${fontSize};
       color: ${p => p.theme.purple};
-    `
+    `)
 
     const H2 = styled(H1)`font-size:32px;`
     const refFunction = jest.fn()
diff --git a/test/react.test.js b/test/react.test.js
index d3e1078c..7a1dbc07 100644
--- a/test/react.test.js
+++ b/test/react.test.js
@@ -4,7 +4,7 @@ import renderer from 'react-test-renderer'
 import serializer from 'jest-glamor-react'
 import { css, sheet } from '../src/index'
 import styled from '../src/react'
-import { ThemeProvider } from '../src/react/theming'
+import { ThemeProvider, withTheme } from 'theming'
 import { mount } from 'enzyme'
 import enzymeToJson from 'enzyme-to-json'
 
@@ -413,18 +413,20 @@ describe('styled', () => {
       height: 64px;
     `
 
-    const Heading = styled('span')`
+    const Heading = withTheme(styled('span')`
       background-color: ${p => p.theme.gold};
-    `
+    `)
 
-    const H1 = styled(Heading)`
+    const H1 = withTheme(styled(Heading)`
       composes: ${cssB};
       font-size: ${fontSize};
       color: ${p => p.theme.purple};
-    `
+    `)
 
     const H2 = styled(H1)`font-size:32px;`
+
     const refFunction = jest.fn()
+
     const tree = renderer
       .create(
         <ThemeProvider theme={theme}>
@@ -525,7 +527,7 @@ describe('styled', () => {
   })
 
   test('change theme', () => {
-    const Div = styled.div`color: ${props => props.theme.primary};`
+    const Div = withTheme(styled.div`color: ${props => props.theme.primary};`)
     const TestComponent = props =>
       <ThemeProvider theme={props.theme}>
         {props.renderChild ? <Div>this will be green then pink</Div> : null}