Skip to content

Commit

Permalink
Forward shouldForwardProp through withComponent
Browse files Browse the repository at this point in the history
- Fixes a bug that prevented `shouldForwardProp` from forwarding to components created via `withComponent`; Fixes emotion-js#1394
- Compacts `createStyled`'s options argument
  • Loading branch information
animecyc committed Dec 5, 2019
1 parent c672175 commit 02c5010
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 7 deletions.
13 changes: 13 additions & 0 deletions packages/styled/__tests__/__snapshots__/styled.js.snap
Expand Up @@ -617,6 +617,12 @@ exports[`styled with higher order component that hoists statics 1`] = `
/>
`;

exports[`styled withComponent composes parent shouldForwardProp 1`] = `
<input
className="emotion-0"
/>
`;

exports[`styled withComponent does carry styles from flattened component 1`] = `
.emotion-0 {
color: green;
Expand All @@ -628,6 +634,13 @@ exports[`styled withComponent does carry styles from flattened component 1`] = `
/>
`;

exports[`styled withComponent inherits parent shouldForwardProp 1`] = `
<input
className="emotion-0"
disabled={true}
/>
`;

exports[`styled withComponent will replace tags but keep styling classes 1`] = `
.emotion-0 {
color: green;
Expand Down
49 changes: 49 additions & 0 deletions packages/styled/__tests__/styled.js
Expand Up @@ -640,6 +640,55 @@ describe('styled', () => {
const tree = renderer.create(<OneMoreComponent />).toJSON()
expect(tree).toMatchSnapshot()
})

test('withComponent inherits parent shouldForwardProp', () => {
const SomeComponent = styled('input', {
shouldForwardProp: prop => prop === 'disabled'
})``
const AnotherComponent = styled('input')``.withComponent(SomeComponent)
const tree = renderer
.create(<AnotherComponent disabled readOnly />)
.toJSON()
expect(tree.props.disabled).toBe(true)
expect(tree.props.readOnly).toBeUndefined()
expect(tree).toMatchSnapshot()
})

test('withComponent composes parent shouldForwardProp', () => {
const shouldForwardPropA = jest.fn(() => false)
const shouldForwardPropB = jest.fn(prop => ~['disabled'].indexOf(prop))
const shouldForwardPropC = jest.fn(
prop => ~['disabled', 'readOnly'].indexOf(prop)
)

const SomeComponent = styled('input', {
shouldForwardProp: shouldForwardPropA
})``
.withComponent('input', { shouldForwardProp: shouldForwardPropB })
.withComponent('input', { shouldForwardProp: shouldForwardPropC })

const tree = renderer
.create(<SomeComponent disabled readOnly multiple />)
.toJSON()

expect(shouldForwardPropC).toHaveBeenCalledTimes(4)
expect(shouldForwardPropC).toHaveBeenNthCalledWith(1, 'as')
expect(shouldForwardPropC).toHaveBeenNthCalledWith(2, 'disabled')
expect(shouldForwardPropC).toHaveBeenNthCalledWith(3, 'readOnly')
expect(shouldForwardPropC).toHaveBeenNthCalledWith(4, 'multiple')

expect(shouldForwardPropB).toHaveBeenCalledTimes(3)
expect(shouldForwardPropB).toHaveBeenNthCalledWith(1, 'as')
expect(shouldForwardPropB).toHaveBeenNthCalledWith(2, 'disabled')
expect(shouldForwardPropB).toHaveBeenNthCalledWith(3, 'readOnly')

expect(shouldForwardPropA).toHaveBeenCalledTimes(2)
expect(shouldForwardPropA).toHaveBeenNthCalledWith(1, 'as')
expect(shouldForwardPropA).toHaveBeenNthCalledWith(2, 'disabled')

expect(tree).toMatchSnapshot()
})

test('theming', () => {
const Div = styled.div`
color: ${props => props.theme.primary};
Expand Down
17 changes: 10 additions & 7 deletions packages/styled/src/base.js
Expand Up @@ -36,7 +36,6 @@ let createStyled: CreateStyled = (tag: any, options?: StyledOptions) => {
tag.__emotion_forwardProp && options.shouldForwardProp
? propName =>
tag.__emotion_forwardProp(propName) &&
// $FlowFixMe
options.shouldForwardProp(propName)
: options.shouldForwardProp
}
Expand Down Expand Up @@ -196,12 +195,16 @@ let createStyled: CreateStyled = (tag: any, options?: StyledOptions) => {
nextTag: ElementType,
nextOptions?: StyledOptions
) => {
return createStyled(
nextTag,
nextOptions !== undefined
? { ...(options || {}), ...nextOptions }
: options
)(...styles)
return createStyled(nextTag, {
...options,
...nextOptions,
shouldForwardProp:
nextOptions && typeof nextOptions.shouldForwardProp === 'function'
? propName =>
nextOptions.shouldForwardProp(propName) &&
defaultShouldForwardProp(propName)
: defaultShouldForwardProp
})(...styles)
}

return Styled
Expand Down

0 comments on commit 02c5010

Please sign in to comment.