Skip to content

Commit a87ef1a

Browse files
nkzawarauchg
authored andcommittedDec 19, 2016
Incorporate styled-jsx (vercel#420)
* integrate styled-jsx * define styles of pages with styled-jsx * bump styled-jsx * bump styled-jsx * error-debug: fix style * bump styled-jsx * fix examples to use styled-jsx * bump styled-jsx
1 parent 26c485a commit a87ef1a

File tree

12 files changed

+167
-181
lines changed

12 files changed

+167
-181
lines changed
 

‎bench/fixtures/basic/pages/css.js

-21
This file was deleted.

‎examples/basic-css/pages/index.js

+13-13
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
import React from 'react'
2-
import style from 'next/css'
32

43
export default () => (
5-
<div className={styles}>
4+
<div className='hello'>
65
<p>Hello World</p>
6+
<style jsx>{`
7+
.hello {
8+
font: 15px Helvetica, Arial, sans-serif;
9+
background: #eee;
10+
padding: 100px;
11+
text-align: center;
12+
transition: 100ms ease-in background;
13+
}
14+
.hello:hover {
15+
background: #ccc;
16+
}
17+
`}</style>
718
</div>
819
)
9-
10-
const styles = style({
11-
font: '15px Helvetica, Arial, sans-serif',
12-
background: '#eee',
13-
padding: '100px',
14-
textAlign: 'center',
15-
transition: '100ms ease-in background',
16-
':hover': {
17-
background: '#ccc'
18-
}
19-
})

‎examples/nested-components/components/paragraph.js

+9-7
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import React from 'react'
2-
import style from 'next/css'
32

43
export default ({ children }) => (
5-
<p className={styles}>{children}</p>
4+
<p>
5+
{children}
6+
<style jsx>{`
7+
p {
8+
font: 13px Helvetica, Arial;
9+
margin: 10px 0;
10+
}
11+
`}</style>
12+
</p>
613
)
7-
8-
const styles = style({
9-
font: '13px Helvetica, Arial',
10-
margin: '10px 0'
11-
})
+15-15
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
import React from 'react'
2-
import style from 'next/css'
32

43
export default ({ title, children }) => (
5-
<div className={mainStyle}>
6-
<h1 className={titleStyle}>{ title }</h1>
4+
<div className='main'>
5+
<h1>{ title }</h1>
76
{ children }
7+
<style jsx>{`
8+
.main {
9+
font: 15px Helvetica, Arial;
10+
border: 1px solid #eee;
11+
padding: 0 10px;
12+
}
13+
14+
h1 {
15+
font-size: 16px;
16+
font-weight: bold;
17+
margin: 10px 0;
18+
}
19+
`}</style>
820
</div>
921
)
10-
11-
const mainStyle = style({
12-
font: '15px Helvetica, Arial',
13-
border: '1px solid #eee',
14-
padding: '0 10px'
15-
})
16-
17-
const titleStyle = style({
18-
fontSize: '16px',
19-
fontWeight: 'bold',
20-
margin: '10px 0'
21-
})
+23-25
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,46 @@
11
import React from 'react'
22
import P from '../components/paragraph'
33
import Post from '../components/post'
4-
import style from 'next/css'
54

65
export default () => (
7-
<div className={styles.main}>
6+
<div className='main'>
87
<Post title='My first blog post'>
98
<P>Hello there</P>
109
<P>This is an example of a componentized blog post</P>
1110
</Post>
1211

13-
<Hr />
12+
<hr />
1413

1514
<Post title='My second blog post'>
1615
<P>Hello there</P>
1716
<P>This is another example.</P>
1817
<P>Wa-hoo!</P>
1918
</Post>
2019

21-
<Hr />
20+
<hr />
2221

2322
<Post title='The final blog post'>
2423
<P>C'est fin</P>
2524
</Post>
25+
26+
<style jsx>{`
27+
.main {
28+
margin: auto;
29+
max-width: 420px;
30+
padding: 10px;
31+
}
32+
33+
hr {
34+
width: 100px;
35+
border-width: 0;
36+
margin: 20px auto;
37+
text-align: center;
38+
}
39+
40+
hr::before {
41+
content: "***";
42+
color: #ccc;
43+
}
44+
`}</style>
2645
</div>
2746
)
28-
29-
const Hr = () => <hr className={styles.hr} />
30-
31-
const styles = {
32-
main: style({
33-
margin: 'auto',
34-
maxWidth: '420px',
35-
padding: '10px'
36-
}),
37-
38-
hr: style({
39-
width: '100px',
40-
borderWidth: 0,
41-
margin: '20px auto',
42-
textAlign: 'center',
43-
'::before': {
44-
content: '"***"',
45-
color: '#ccc'
46-
}
47-
})
48-
}

‎package.json

+1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
"send": "0.14.1",
6666
"source-map-support": "0.4.6",
6767
"strip-ansi": "3.0.1",
68+
"styled-jsx": "0.2.1",
6869
"url": "0.11.0",
6970
"webpack": "1.14.0",
7071
"webpack-dev-middleware": "1.9.0",

‎pages/_error-debug.js

+38-48
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import React from 'react'
22
import ansiHTML from 'ansi-html'
3-
import Head from 'next/head'
4-
import style from 'next/css'
53

64
export default class ErrorDebug extends React.Component {
75
static getInitialProps ({ err }) {
@@ -12,21 +10,47 @@ export default class ErrorDebug extends React.Component {
1210
render () {
1311
const { name, message, stack, path } = this.props
1412

15-
return <div className={styles.errorDebug}>
16-
<Head>
17-
<style dangerouslySetInnerHTML={{ __html: `
18-
body {
19-
background: #a6004c;
20-
margin: 0;
21-
}
22-
`}} />
23-
</Head>
24-
{path ? <div className={styles.heading}>Error in {path}</div> : null}
13+
return <div className='errorDebug'>
14+
{path ? <div className='heading'>Error in {path}</div> : null}
2515
{
2616
name === 'ModuleBuildError'
27-
? <pre className={styles.message} dangerouslySetInnerHTML={{ __html: ansiHTML(encodeHtml(message)) }} />
28-
: <pre className={styles.message}>{stack}</pre>
17+
? <pre className='message' dangerouslySetInnerHTML={{ __html: ansiHTML(encodeHtml(message)) }} />
18+
: <pre className='message'>{stack}</pre>
2919
}
20+
<style jsx global>{`
21+
body {
22+
background: #a6004c;
23+
margin: 0;
24+
}
25+
`}</style>
26+
<style jsx>{`
27+
.errorDebug {
28+
height: 100vh;
29+
padding: 16px;
30+
box-sizing: border-box;
31+
display: flex;
32+
flex-direction: column;
33+
align-items: center;
34+
justify-content: center;
35+
}
36+
37+
.message {
38+
font-family: "SF Mono", "Roboto Mono", "Fira Mono", menlo-regular, monospace;
39+
font-size: 10px;
40+
color: #fbe7f1;
41+
margin: 0;
42+
white-space: pre-wrap;
43+
word-wrap: break-word;
44+
}
45+
46+
.heading {
47+
font-family: -apple-system, BlinkMacSystemFont, Roboto, "Segoe UI", "Fira Sans", Avenir, "Helvetica Neue", "Lucida Grande", sans-serif;
48+
font-size: 13px;
49+
font-weight: bold;
50+
color: #ff84bf;
51+
margin-bottom: 20pxl
52+
}
53+
`}</style>
3054
</div>
3155
}
3256
}
@@ -35,40 +59,6 @@ const encodeHtml = str => {
3559
return str.replace(/</g, '&lt;').replace(/>/g, '&gt;')
3660
}
3761

38-
const styles = {
39-
body: style({
40-
background: '#a6004c',
41-
margin: 0
42-
}),
43-
44-
errorDebug: style({
45-
height: '100vh',
46-
padding: '16px',
47-
boxSizing: 'border-box',
48-
display: 'flex',
49-
flexDirection: 'column',
50-
alignItems: 'center',
51-
justifyContent: 'center'
52-
}),
53-
54-
message: style({
55-
fontFamily: '"SF Mono", "Roboto Mono", "Fira Mono", menlo-regular, monospace',
56-
fontSize: '10px',
57-
color: '#fbe7f1',
58-
margin: 0,
59-
whiteSpace: 'pre-wrap',
60-
wordWrap: 'break-word'
61-
}),
62-
63-
heading: style({
64-
fontFamily: '-apple-system, BlinkMacSystemFont, Roboto, "Segoe UI", "Fira Sans", Avenir, "Helvetica Neue", "Lucida Grande", sans-serif',
65-
fontSize: '13px',
66-
fontWeight: 'bold',
67-
color: '#ff84bf',
68-
marginBottom: '20px'
69-
})
70-
}
71-
7262
// see color definitions of babel-code-frame:
7363
// https://github.com/babel/babel/blob/master/packages/babel-code-frame/src/index.js
7464

‎pages/_error.js

+44-46
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import React from 'react'
2-
import style from 'next/css'
32

43
export default class Error extends React.Component {
54
static getInitialProps ({ res, xhr }) {
@@ -13,54 +12,53 @@ export default class Error extends React.Component {
1312
? 'This page could not be found'
1413
: (statusCode ? 'Internal Server Error' : 'An unexpected error has occurred')
1514

16-
return <div className={styles.error}>
17-
<div className={styles.text}>
18-
{statusCode ? <h1 className={styles.h1}>{statusCode}</h1> : null}
19-
<div className={styles.desc}>
20-
<h2 className={styles.h2}>{title}.</h2>
15+
return <div className='error'>
16+
<div>
17+
{statusCode ? <h1>{statusCode}</h1> : null}
18+
<div className='desc'>
19+
<h2>{title}.</h2>
2120
</div>
2221
</div>
23-
</div>
24-
}
25-
}
22+
<style jsx>{`
23+
.error {
24+
color: #000;
25+
background: #fff;
26+
top: 0;
27+
bottom: 0;
28+
left: 0;
29+
right: 0;
30+
position: absolute;
31+
font-family: -apple-system, BlinkMacSystemFont, Roboto, "Segoe UI", "Fira Sans", Avenir, "Helvetica Neue", "Lucida Grande", sans-serif;
32+
text-align: center;
33+
padding-top: 20%;
34+
}
2635
27-
const styles = {
28-
error: style({
29-
color: '#000',
30-
background: '#fff',
31-
top: 0,
32-
bottom: 0,
33-
left: 0,
34-
right: 0,
35-
position: 'absolute',
36-
fontFamily: '-apple-system, BlinkMacSystemFont, Roboto, "Segoe UI", "Fira Sans", Avenir, "Helvetica Neue", "Lucida Grande", sans-serif',
37-
textAlign: 'center',
38-
paddingTop: '20%'
39-
}),
36+
.desc {
37+
display: inline-block;
38+
text-align: left;
39+
line-height: 49px;
40+
height: 49px;
41+
vertical-align: middle;
42+
}
4043
41-
desc: style({
42-
display: 'inline-block',
43-
textAlign: 'left',
44-
lineHeight: '49px',
45-
height: '49px',
46-
verticalAlign: 'middle'
47-
}),
44+
h1 {
45+
display: inline-block;
46+
border-right: 1px solid rgba(0, 0, 0,.3);
47+
margin: 0;
48+
margin-right: 20px;
49+
padding: 10px 23px;
50+
font-size: 24px;
51+
font-weight: 500;
52+
vertical-align: top;
53+
}
4854
49-
h1: style({
50-
display: 'inline-block',
51-
borderRight: '1px solid rgba(0, 0, 0,.3)',
52-
margin: 0,
53-
marginRight: '20px',
54-
padding: '10px 23px',
55-
fontSize: '24px',
56-
fontWeight: 500,
57-
verticalAlign: 'top'
58-
}),
59-
60-
h2: style({
61-
fontSize: '14px',
62-
fontWeight: 'normal',
63-
margin: 0,
64-
padding: 0
65-
})
55+
h2 {
56+
font-size: 14px;
57+
font-weight: normal;
58+
margin: 0;
59+
padding: 0;
60+
}
61+
`}</style>
62+
</div>
63+
}
6664
}

‎server/build/webpack.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ export default async function createCompiler (dir, { dev = false } = {}) {
120120
require.resolve('babel-plugin-module-resolver'),
121121
{
122122
alias: {
123-
'ansi-html': require.resolve('ansi-html')
123+
'ansi-html': require.resolve('ansi-html'),
124+
'styled-jsx/style': require.resolve('styled-jsx/style')
124125
}
125126
}
126127
]
@@ -143,6 +144,7 @@ export default async function createCompiler (dir, { dev = false } = {}) {
143144
require.resolve('babel-plugin-transform-object-rest-spread'),
144145
require.resolve('babel-plugin-transform-class-properties'),
145146
require.resolve('babel-plugin-transform-runtime'),
147+
require.resolve('styled-jsx/babel'),
146148
[
147149
require.resolve('babel-plugin-module-resolver'),
148150
{
@@ -154,7 +156,8 @@ export default async function createCompiler (dir, { dev = false } = {}) {
154156
'next/prefetch': require.resolve('../../lib/prefetch'),
155157
'next/css': require.resolve('../../lib/css'),
156158
'next/head': require.resolve('../../lib/head'),
157-
'next/document': require.resolve('../../server/document')
159+
'next/document': require.resolve('../../server/document'),
160+
'styled-jsx/style': require.resolve('styled-jsx/style')
158161
}
159162
}
160163
]

‎server/document.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React, { Component, PropTypes } from 'react'
22
import htmlescape from 'htmlescape'
33
import { renderStatic } from 'glamor/server'
4+
import flush from 'styled-jsx/server'
45

56
export default class Document extends Component {
67
static getInitialProps ({ renderPage }) {
@@ -10,7 +11,8 @@ export default class Document extends Component {
1011
head = page.head
1112
return page.html
1213
})
13-
const nextCSS = { css, ids }
14+
const styles = flush()
15+
const nextCSS = { css, ids, styles }
1416
return { html, head, nextCSS }
1517
}
1618

@@ -48,7 +50,8 @@ export class Head extends Component {
4850
const { head, nextCSS } = this.context._documentProps
4951
return <head>
5052
{(head || []).map((h, i) => React.cloneElement(h, { key: i }))}
51-
{nextCSS ? <style dangerouslySetInnerHTML={{ __html: nextCSS.css }} /> : null}
53+
{nextCSS && nextCSS.css ? <style dangerouslySetInnerHTML={{ __html: nextCSS.css }} /> : null}
54+
{nextCSS && nextCSS.styles ? nextCSS.styles : null}
5255
{this.props.children}
5356
</head>
5457
}
+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export default () => (
2+
<div>
3+
<p>This is blue</p>
4+
<style jsx>{`p { color: blue }`}</style>
5+
</div>
6+
)

‎test/integration.test.js

+8-2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ describe('integration tests', () => {
4545
expect(/<div class="css-\w+">This is red<\/div>/.test(html)).toBeTruthy()
4646
})
4747

48+
test('renders styled jsx', async () => {
49+
const html = await render('/styled-jsx')
50+
expect(html).toMatch(/<style id="__jsx-style-1401785258">p\[data-jsx="1401785258"] {color: blue }[^]+<\/style>/)
51+
expect(html.includes('<div data-jsx="1401785258"><p data-jsx="1401785258">This is blue</p></div>')).toBeTruthy()
52+
})
53+
4854
test('renders properties populated asynchronously', async () => {
4955
const html = await render('/async-props')
5056
expect(html.includes('<p>Diego Milito</p>')).toBeTruthy()
@@ -62,8 +68,8 @@ describe('integration tests', () => {
6268

6369
test('error 404', async () => {
6470
const html = await render('/non-existent')
65-
expect(html).toMatch(/<h1 class=".+">404<\/h1>/)
66-
expect(html).toMatch(/<h2 class=".+">This page could not be found\.<\/h2>/)
71+
expect(html).toMatch(/<h1 data-jsx=".+">404<\/h1>/)
72+
expect(html).toMatch(/<h2 data-jsx=".+">This page could not be found\.<\/h2>/)
6773
})
6874

6975
test('finishes response', async () => {

0 commit comments

Comments
 (0)
Please sign in to comment.