Skip to content

Commit c5c270c

Browse files
committed
Merge master into v3-beta.
2 parents 0c7089f + 0f3fecf commit c5c270c

File tree

12 files changed

+249
-29
lines changed

12 files changed

+249
-29
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
export default ({message}) => (
2+
<aside>
3+
{message}
4+
<style jsx>{`
5+
aside {
6+
padding: 1.5em;
7+
font-size: 14px;
8+
color: white;
9+
background-color: red;
10+
}
11+
`}</style>
12+
</aside>
13+
)

examples/with-apollo-and-redux/components/PostList.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import { gql, graphql } from 'react-apollo'
2+
import ErrorMessage from './ErrorMessage'
23
import PostUpvoter from './PostUpvoter'
34

45
const POSTS_PER_PAGE = 10
56

6-
function PostList ({ data: { allPosts, loading, _allPostsMeta }, loadMorePosts }) {
7+
function PostList ({ data: { loading, error, allPosts, _allPostsMeta }, loadMorePosts }) {
8+
if (error) return <ErrorMessage message='Error loading posts.' />
79
if (allPosts && allPosts.length) {
810
const areMorePosts = allPosts.length < _allPostsMeta.count
911
return (

examples/with-apollo-and-redux/lib/withData.js

+23-13
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,14 @@ import Head from 'next/head'
55
import initApollo from './initApollo'
66
import initRedux from './initRedux'
77

8+
// Gets the display name of a JSX component for dev tools
9+
function getComponentDisplayName (Component) {
10+
return Component.displayName || Component.name || 'Unknown'
11+
}
12+
813
export default ComposedComponent => {
914
return class WithData extends React.Component {
10-
static displayName = `WithData(${ComposedComponent.displayName})`
15+
static displayName = `WithData(${getComponentDisplayName(ComposedComponent)})`
1116
static propTypes = {
1217
serverState: PropTypes.object.isRequired
1318
}
@@ -21,23 +26,28 @@ export default ComposedComponent => {
2126
composedInitialProps = await ComposedComponent.getInitialProps(ctx)
2227
}
2328

24-
// Run all graphql queries in the component tree
29+
// Run all GraphQL queries in the component tree
2530
// and extract the resulting data
2631
if (!process.browser) {
2732
const apollo = initApollo()
2833
const redux = initRedux(apollo)
29-
// Provide the `url` prop data in case a graphql query uses it
34+
// Provide the `url` prop data in case a GraphQL query uses it
3035
const url = {query: ctx.query, pathname: ctx.pathname}
3136

32-
// Run all graphql queries
33-
const app = (
34-
// No need to use the Redux Provider
35-
// because Apollo sets up the store for us
36-
<ApolloProvider client={apollo} store={redux}>
37-
<ComposedComponent url={url} {...composedInitialProps} />
38-
</ApolloProvider>
39-
)
40-
await getDataFromTree(app)
37+
try {
38+
// Run all GraphQL queries
39+
await getDataFromTree(
40+
// No need to use the Redux Provider
41+
// because Apollo sets up the store for us
42+
<ApolloProvider client={apollo} store={redux}>
43+
<ComposedComponent url={url} {...composedInitialProps} />
44+
</ApolloProvider>
45+
)
46+
} catch (error) {
47+
// Prevent Apollo Client GraphQL errors from crashing SSR.
48+
// Handle them in components via the data.error prop:
49+
// http://dev.apollodata.com/react/api-queries.html#graphql-query-data-error
50+
}
4151
// getDataFromTree does not call componentWillUnmount
4252
// head side effect therefore need to be cleared manually
4353
Head.rewind()
@@ -48,7 +58,7 @@ export default ComposedComponent => {
4858
// No need to include other initial Redux state because when it
4959
// initialises on the client-side it'll create it again anyway
5060
serverState = {
51-
apollo: { // Make sure to only include Apollo's data state
61+
apollo: { // Only include the Apollo data state
5262
data: state.apollo.data
5363
}
5464
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
export default ({message}) => (
2+
<aside>
3+
{message}
4+
<style jsx>{`
5+
aside {
6+
padding: 1.5em;
7+
font-size: 14px;
8+
color: white;
9+
background-color: red;
10+
}
11+
`}</style>
12+
</aside>
13+
)

examples/with-apollo/components/PostList.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import { gql, graphql } from 'react-apollo'
2+
import ErrorMessage from './ErrorMessage'
23
import PostUpvoter from './PostUpvoter'
34

45
const POSTS_PER_PAGE = 10
56

6-
function PostList ({ data: { allPosts, loading, _allPostsMeta }, loadMorePosts }) {
7+
function PostList ({ data: { loading, error, allPosts, _allPostsMeta }, loadMorePosts }) {
8+
if (error) return <ErrorMessage message='Error loading posts.' />
79
if (allPosts && allPosts.length) {
810
const areMorePosts = allPosts.length < _allPostsMeta.count
911
return (

examples/with-apollo/lib/withData.js

+23-13
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,14 @@ import { ApolloProvider, getDataFromTree } from 'react-apollo'
44
import Head from 'next/head'
55
import initApollo from './initApollo'
66

7+
// Gets the display name of a JSX component for dev tools
8+
function getComponentDisplayName (Component) {
9+
return Component.displayName || Component.name || 'Unknown'
10+
}
11+
712
export default ComposedComponent => {
813
return class WithData extends React.Component {
9-
static displayName = `WithData(${ComposedComponent.displayName})`
14+
static displayName = `WithData(${getComponentDisplayName(ComposedComponent)})`
1015
static propTypes = {
1116
serverState: PropTypes.object.isRequired
1217
}
@@ -20,29 +25,34 @@ export default ComposedComponent => {
2025
composedInitialProps = await ComposedComponent.getInitialProps(ctx)
2126
}
2227

23-
// Run all graphql queries in the component tree
28+
// Run all GraphQL queries in the component tree
2429
// and extract the resulting data
2530
if (!process.browser) {
2631
const apollo = initApollo()
27-
// Provide the `url` prop data in case a graphql query uses it
32+
// Provide the `url` prop data in case a GraphQL query uses it
2833
const url = {query: ctx.query, pathname: ctx.pathname}
29-
30-
// Run all graphql queries
31-
const app = (
32-
<ApolloProvider client={apollo}>
33-
<ComposedComponent url={url} {...composedInitialProps} />
34-
</ApolloProvider>
35-
)
36-
await getDataFromTree(app)
34+
try {
35+
// Run all GraphQL queries
36+
await getDataFromTree(
37+
<ApolloProvider client={apollo}>
38+
<ComposedComponent url={url} {...composedInitialProps} />
39+
</ApolloProvider>
40+
)
41+
} catch (error) {
42+
// Prevent Apollo Client GraphQL errors from crashing SSR.
43+
// Handle them in components via the data.error prop:
44+
// http://dev.apollodata.com/react/api-queries.html#graphql-query-data-error
45+
}
3746
// getDataFromTree does not call componentWillUnmount
3847
// head side effect therefore need to be cleared manually
3948
Head.rewind()
4049

41-
// Extract query data from the Apollo's store
50+
// Extract query data from the Apollo store
4251
const state = apollo.getInitialState()
4352

4453
serverState = {
45-
apollo: { // Make sure to only include Apollo's data state
54+
apollo: {
55+
// Only include the Apollo data state
4656
data: state.data
4757
}
4858
}

examples/with-emotion/.babelrc

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"presets": [
3+
"next/babel"
4+
],
5+
"plugins": [
6+
["emotion/babel", { "inline": true }]
7+
]
8+
}

examples/with-emotion/README.md

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
[![Deploy to now](https://deploy.now.sh/static/button.svg)](https://deploy.now.sh/?repo=https://github.com/zeit/next.js/tree/master/examples/with-emotion)
2+
3+
# Example app with [emotion](https://github.com/tkh44/emotion)
4+
5+
## How to use
6+
7+
Download the example [or clone the repo](https://github.com/zeit/next.js):
8+
9+
```bash
10+
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/with-emotion
11+
cd with-emotion
12+
```
13+
14+
Install it and run:
15+
16+
```bash
17+
npm install
18+
npm run dev
19+
```
20+
21+
Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download))
22+
23+
```bash
24+
now
25+
```
26+
27+
## The idea behind the example
28+
29+
This example features how to use [emotion](https://github.com/tkh44/emotion) as the styling solution instead of [styled-jsx](https://github.com/zeit/styled-jsx).
30+
31+
We are creating three `div` elements with custom styles being shared across the elements. The styles includes the use of pseedo-selector and CSS animations.
32+
33+
34+
This is based off the with-glamorous example.

examples/with-emotion/package.json

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "with-emotion",
3+
"version": "1.0.0",
4+
"scripts": {
5+
"dev": "next",
6+
"build": "next build",
7+
"start": "next start"
8+
},
9+
"dependencies": {
10+
"emotion": "^5.0.0",
11+
"next": "^2.4.6",
12+
"react": "^15.6.1",
13+
"react-dom": "^15.6.1"
14+
},
15+
"license": "ISC"
16+
}
+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import Document, { Head, Main, NextScript } from 'next/document'
2+
import { extractCritical } from 'emotion/server'
3+
4+
export default class MyDocument extends Document {
5+
static getInitialProps ({ renderPage }) {
6+
const page = renderPage()
7+
const styles = extractCritical(page.html)
8+
return { ...page, ...styles }
9+
}
10+
11+
constructor (props) {
12+
super(props)
13+
const { __NEXT_DATA__, ids } = props
14+
if (ids) {
15+
__NEXT_DATA__.ids = this.props.ids
16+
}
17+
}
18+
19+
render () {
20+
return (
21+
<html>
22+
<Head>
23+
<title>With Emotion</title>
24+
<style dangerouslySetInnerHTML={{ __html: this.props.css }} />
25+
</Head>
26+
<body>
27+
<Main />
28+
<NextScript />
29+
</body>
30+
</html>
31+
)
32+
}
33+
}

examples/with-emotion/pages/index.js

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import React from 'react'
2+
import { hydrate, keyframes, fragment, injectGlobal } from 'emotion'
3+
import styled from 'emotion/react'
4+
5+
// Adds server generated styles to emotion cache.
6+
// '__NEXT_DATA__.ids' is set in '_document.js'
7+
if (typeof window !== 'undefined') {
8+
hydrate(window.__NEXT_DATA__.ids)
9+
}
10+
11+
export default () => {
12+
injectGlobal`
13+
html, body {
14+
padding: 3rem 1rem;
15+
margin: 0;
16+
background: papayawhip;
17+
min-height: 100%;
18+
font-family: Helvetica, Arial, sans-serif;
19+
font-size: 24px;
20+
}
21+
`
22+
23+
const basicStyles = fragment`
24+
background-color: white;
25+
color: cornflowerblue;
26+
border: 1px solid lightgreen;
27+
border-right: none;
28+
border-bottom: none;
29+
box-shadow: 5px 5px 0 0 lightgreen, 10px 10px 0 0 lightyellow;
30+
transition: all 0.1s linear;
31+
margin: 3rem 0;
32+
padding: 1rem 0.5rem;
33+
`
34+
const hoverStyles = fragment`
35+
color: white;
36+
background-color: lightgray;
37+
border-color: aqua;
38+
box-shadow: -15px -15px 0 0 aqua, -30px -30px 0 0 cornflowerblue;
39+
`
40+
const bounce = keyframes`
41+
from {
42+
transform: scale(1.01);
43+
}
44+
to {
45+
transform: scale(0.99);
46+
}
47+
`
48+
49+
const Basic = styled.div`@apply ${basicStyles};`
50+
const Combined = styled.div`
51+
@apply ${basicStyles};
52+
&:hover {
53+
@apply ${hoverStyles};
54+
}
55+
& code {
56+
background-color: linen;
57+
}
58+
`
59+
const Animated = styled.div`
60+
@apply ${basicStyles};
61+
&:hover {
62+
@apply ${hoverStyles};
63+
}
64+
& code {
65+
background-color: linen;
66+
}
67+
animation: ${props => props.animation} 0.2s infinite ease-in-out alternate;
68+
`
69+
70+
return (
71+
<div>
72+
<Basic>Cool Styles</Basic>
73+
<Combined>
74+
With <code>:hover</code>.
75+
</Combined>
76+
<Animated animation={bounce}>Let's bounce.</Animated>
77+
</div>
78+
)
79+
}

server/build/clean.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ import getConfig from '../config'
44

55
export default function clean (dir) {
66
const dist = getConfig(dir).distDir
7-
return del(resolve(dir, dist))
7+
return del(resolve(dir, dist), { force: true })
88
}

0 commit comments

Comments
 (0)