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

Emotion SWC Plugin - Allow for jsxImportSource to be configurable #35963

Merged
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/next/build/swc/options.js
Expand Up @@ -64,9 +64,9 @@ function getBaseSWCOptions({
legacyDecorator: enableDecorators,
decoratorMetadata: emitDecoratorMetadata,
react: {
importSource: nextConfig?.experimental?.emotion
? '@emotion/react'
: jsConfig?.compilerOptions?.jsxImportSource || 'react',
importSource:
jsConfig?.compilerOptions?.jsxImportSource ??
(nextConfig?.experimental?.emotion ? '@emotion/react' : 'react'),
runtime: 'automatic',
pragma: 'React.createElement',
pragmaFrag: 'React.Fragment',
Expand Down
43 changes: 43 additions & 0 deletions test/development/basic/emotion-swc.test.ts
@@ -0,0 +1,43 @@
import { join } from 'path'
import webdriver from 'next-webdriver'
import { createNext, FileRef } from 'e2e-utils'
import { NextInstance } from 'test/lib/next-modes/base'

describe('emotion SWC option', () => {
let next: NextInstance

beforeAll(async () => {
next = await createNext({
files: {
'jsconfig.json': new FileRef(
join(__dirname, 'emotion-swc/jsconfig.json')
),
pages: new FileRef(join(__dirname, 'emotion-swc/pages')),
shared: new FileRef(join(__dirname, 'emotion-swc/shared')),
'next.config.js': new FileRef(
join(__dirname, 'emotion-swc/next.config.js')
),
},
dependencies: {
'@emotion/core': '^10.0.35',
'@emotion/styled': '^10.0.27',
},
})
})
afterAll(() => next.destroy())

it('should have styling from the css prop', async () => {
let browser
try {
browser = await webdriver(next.appPort, '/')
const color = await browser
.elementByCss('#test-element')
.getComputedCss('background-color')
expect(color).toBe('rgb(255, 192, 203)')
} finally {
if (browser) {
await browser.close()
}
}
})
})
5 changes: 5 additions & 0 deletions test/development/basic/emotion-swc/jsconfig.json
@@ -0,0 +1,5 @@
{
"compilerOptions": {
"jsxImportSource": "@emotion/core"
}
}
10 changes: 10 additions & 0 deletions test/development/basic/emotion-swc/next.config.js
@@ -0,0 +1,10 @@
/** @type {import('next').NextConfig} */

const nextConfig = {
reactStrictMode: true,
experimental: {
emotion: true,
},
}

module.exports = nextConfig
15 changes: 15 additions & 0 deletions test/development/basic/emotion-swc/pages/_app.js
@@ -0,0 +1,15 @@
import createCache from '@emotion/cache'
import { CacheProvider } from '@emotion/core'

import { globalStyles } from '../shared/styles'

const cache = createCache({ key: 'next' })

const App = ({ Component, pageProps }) => (
<CacheProvider value={cache}>
{globalStyles}
<Component {...pageProps} />
</CacheProvider>
)

export default App
33 changes: 33 additions & 0 deletions test/development/basic/emotion-swc/pages/index.js
@@ -0,0 +1,33 @@
import { css } from '@emotion/core'
import {
Animated,
Basic,
bounce,
Combined,
Pink,
BasicExtended,
ComponentSelectorsExtended,
} from '../shared/styles'

const Home = () => (
<div
id={'test-element'}
css={css`
display: flex;
flex-direction: column;
background-color: pink;
`}
>
<Basic>Cool Styles</Basic>
<Pink>Pink text</Pink>
<Combined>
With <code>:hover</code>.
</Combined>
<Animated animation={bounce}>Let's bounce.</Animated>
<ComponentSelectorsExtended>
<BasicExtended>Nested</BasicExtended>
</ComponentSelectorsExtended>
</div>
)

export default Home
81 changes: 81 additions & 0 deletions test/development/basic/emotion-swc/shared/styles.js
@@ -0,0 +1,81 @@
import { css, Global, keyframes } from '@emotion/core'
import styled from '@emotion/styled'

export const globalStyles = (
<Global
styles={css`
html,
body {
padding: 3rem 1rem;
margin: 0;
background: papayawhip;
min-height: 100%;
font-family: Helvetica, Arial, sans-serif;
font-size: 24px;
}
`}
/>
)

export const basicStyles = css({
backgroundColor: 'white',
color: 'cornflowerblue',
border: '1px solid lightgreen',
borderRight: 'none',
borderBottom: 'none',
boxShadow: '5px 5px 0 0 lightgreen, 10px 10px 0 0 lightyellow',
transition: 'all 0.1s linear',
margin: '3rem 0',
padding: '1rem 0.5rem',
})

export const hoverStyles = css`
&:hover {
color: white;
background-color: lightgray;
border-color: aqua;
box-shadow: -15px -15px 0 0 aqua, -30px -30px 0 0 cornflowerblue;
}
`
export const bounce = keyframes`
from {
transform: scale(1.01);
}
to {
transform: scale(0.99);
}
`

export const Basic = styled.div`
${basicStyles};
`

export const Combined = styled.div`
${basicStyles};
${hoverStyles};
& code {
background-color: linen;
}
`

export const Pink = styled(Basic)({
color: 'hotpink',
})

export const BasicExtended = styled(Basic)``

export const ComponentSelectorsExtended = styled.div`
${BasicExtended} {
color: green;
}
box-shadow: -5px -5px 0 0 green;
`

export const Animated = styled.div`
${basicStyles};
${hoverStyles};
& code {
background-color: linen;
}
animation: ${({ animation }) => animation} 0.2s infinite ease-in-out alternate;
`