Skip to content

Commit

Permalink
Allow Styled tags to be updated via withComponent (#232)
Browse files Browse the repository at this point in the history
* feat(withComponent) Allow changing of tag/component

- Add `withComponent` method to create new styled component
- Update react test
- Update snapshot

* Update styled-with-component.md

* Fix linting error

* Update snapshots

* Update index.js
  • Loading branch information
ifyoumakeit authored and emmatown committed Sep 25, 2017
1 parent e4c5b29 commit d89fae5
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 7 deletions.
3 changes: 3 additions & 0 deletions docs/styled-with-component.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## withComponent

You can change a `styled` component's tag with the method `withComponent`. This API was inspired by [styled-components' `withComponent`](https://www.styled-components.com/docs/api#withcomponent).
8 changes: 7 additions & 1 deletion packages/react-emotion/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const omitAssign = function(testFn, target) {
return target
}

export default function(tag, options: { e: string }) {
const createStyled = (tag, options: { e: string }) => {
if (process.env.NODE_ENV !== 'production') {
if (tag === undefined) {
throw new Error(
Expand Down Expand Up @@ -90,6 +90,12 @@ export default function(tag, options: { e: string }) {
Styled.__emotion_styles = styles
Styled.__emotion_base = baseTag

Styled.withComponent = nextTag => {
return createStyled(nextTag, options)(styles)
}

return Styled
}
}

export default createStyled
23 changes: 23 additions & 0 deletions packages/react-emotion/test/__snapshots__/index.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -619,3 +619,26 @@ exports[`styled throws if undefined is passed as the component 1`] = `
"You are trying to create a styled element with an undefined component.
You may have forgotten to import it."
`;

exports[`styled withComponent will replace tags but keep styling classes 1`] = `
.glamor-0 {
color: green;
}
<article>
<Styled>
<h1
className="glamor-0"
>
My Title
</h1>
</Styled>
<Styled>
<h2
className="glamor-0"
>
My Subtitle
</h2>
</Styled>
</article>
`;
13 changes: 13 additions & 0 deletions packages/react-emotion/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -601,4 +601,17 @@ describe('styled', () => {
() => styled(undefined)`display: flex;`
).toThrowErrorMatchingSnapshot()
})
test('withComponent will replace tags but keep styling classes', () => {
const Title = styled('h1')`color: green;`
const Subtitle = Title.withComponent('h2')

const wrapper = mount(
<article>
<Title>My Title</Title>
<Subtitle>My Subtitle</Subtitle>
</article>
)

expect(enzymeToJson(wrapper)).toMatchSnapshot()
})
})
9 changes: 9 additions & 0 deletions packages/site/src/blocks/styled-with-component.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const Circle = styled('span')`
width: 96px;
height: 96px;
border-radius: 50%;
`

const Avatar = Circle.withComponent('img')

render(<Circle><Avatar src={logoUrl} /></Circle>)
7 changes: 1 addition & 6 deletions packages/site/src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,6 @@ import Playground from './playground'
import logoUrl from '../../../emotion.png'

const introExample = require('./blocks/intro.example')
// const propsExample = require('./blocks/props.example')
// const nestedExample = require('./blocks/nested.example')
// const mediaExample = require('./blocks/media.example')
// const anyComponentExample = require('./blocks/styling-any-component.example')
// const pseudoExample = require('./blocks/pseudo.example')
// const keyframesExample = require('./blocks/keyframes.example')

const scope = {
logoUrl,
Expand Down Expand Up @@ -115,6 +109,7 @@ const docs = [
{ name: 'pseudo', hasCodeExample: true },
{ name: 'media', hasCodeExample: true },
{ name: 'styling-any-component', hasCodeExample: true },
{ name: 'styled-with-component', hasCodeExample: true },
{ name: 'props', hasCodeExample: true },
{ name: 'keyframes', hasCodeExample: true },
{ name: 'composition', hasCodeExample: true },
Expand Down

0 comments on commit d89fae5

Please sign in to comment.