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

feature/vanilla-emotion - add an example of vanilla emotion #20228

Merged
merged 15 commits into from
Jan 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions examples/with-emotion-vanilla/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"presets": [["next/babel"]],
"plugins": ["@emotion/babel-plugin"]
}
34 changes: 34 additions & 0 deletions examples/with-emotion-vanilla/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env.local
.env.development.local
.env.test.local
.env.production.local

# vercel
.vercel
24 changes: 24 additions & 0 deletions examples/with-emotion-vanilla/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Emotion Vanilla Example

Extract and inline critical css with
[emotion](https://github.com/emotion-js/emotion/tree/master/packages/emotion),
[@emotion/server](https://github.com/emotion-js/emotion/tree/master/packages/server),
[@emotion/css](https://github.com/emotion-js/emotion/tree/master/packages/css)

## Deploy your own

Deploy the example using [Vercel](https://vercel.com):

[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/import/project?template=https://github.com/vercel/next.js/tree/canary/examples/with-emotion-vanilla)

## How to use

Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:

```bash
npx create-next-app --example with-emotion-vanilla with-emotion-vanilla-app
# or
yarn create next-app --example with-emotion-vanilla with-emotion-vanilla-app
```

Deploy it to the cloud with [Vercel](https://vercel.com/import?filter=next.js&utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).
20 changes: 20 additions & 0 deletions examples/with-emotion-vanilla/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "with-emotion-vanilla",
"version": "1.0.0",
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start"
},
"license": "MIT",
"devDependencies": {
"@emotion/babel-plugin": "11.0.0"
},
"dependencies": {
"@emotion/css": "11.0.0",
"@emotion/server": "11.0.0",
"next": "latest",
"react": "^17.0.1",
"react-dom": "^17.0.1"
}
}
34 changes: 34 additions & 0 deletions examples/with-emotion-vanilla/pages/_document.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import Document, { Html, Head, Main, NextScript } from 'next/document'
import * as React from 'react'
import { renderStatic } from '../shared/renderer'
export default class AppDocument extends Document {
static async getInitialProps(ctx) {
const page = await ctx.renderPage()
const { css, ids } = await renderStatic(page.html)
const initialProps = await Document.getInitialProps(ctx)
return {
...initialProps,
styles: (
<React.Fragment>
{initialProps.styles}
<style
data-emotion={`css ${ids.join(' ')}`}
dangerouslySetInnerHTML={{ __html: css }}
/>
</React.Fragment>
),
}
}

render() {
return (
<Html>
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
30 changes: 30 additions & 0 deletions examples/with-emotion-vanilla/pages/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import Head from 'next/head'
import {
basicStyles,
otherStyles,
someMoreBasicStyles,
someCssAsObject,
combinedAsArray,
cxExample,
keyframesExample,
} from '../shared/styles'

const Home = () => (
<>
<Head>
<title>Emotion using the vanilla version supporting SSR</title>
</Head>
<div>
<h1>Emotion Vanilla example</h1>
<div className={basicStyles}>Basic styles using emotion</div>
<div className={otherStyles}>Some more styles using emotion</div>
<div className={someMoreBasicStyles}>Well why not here is some more</div>
<div className={someCssAsObject}>Object styles using emotion css</div>
<div className={combinedAsArray}>Array of styles using emotion css</div>
<div className={cxExample}>cx example from emotion</div>
<div className={keyframesExample} />
</div>
</>
)

export default Home
12 changes: 12 additions & 0 deletions examples/with-emotion-vanilla/shared/renderer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import createEmotionServer from '@emotion/server/create-instance'
import { cache } from '@emotion/css'

export const renderStatic = async (html) => {
if (html === undefined) {
throw new Error('did you forget to return html from renderToString?')
}
const { extractCritical } = createEmotionServer(cache)
const { ids, css } = extractCritical(html)

return { html, ids, css }
}
102 changes: 102 additions & 0 deletions examples/with-emotion-vanilla/shared/styles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { css, cx, keyframes, injectGlobal } from '@emotion/css'

injectGlobal`
* {
box-sizing: border-box;
}
body {
background: #DFCFBE;
font-family: Helvetica, sans-serif;
}
`

const basicStyles = css`
background-color: white;
color: cornflowerblue;
border: 1px solid lightgreen;
border-right: none;
border-bottom: none;
box-shadow: 5px 5px 0 0 lightgreen, 10px 10px 0 0 lightyellow;
transition: all 0.1s linear;
margin: 3rem 0;
padding: 1rem 0.5rem;
`

const otherStyles = css`
background-color: red;
padding: 10px;
margin-bottom: 10px;
`

const someMoreBasicStyles = css`
background-color: green;
color: white;
margin-bottom: 10px;
padding: 10px;
`

const someCssAsObject = css({
background: 'orange',
color: 'white',
padding: '10px',
marginBottom: '10px',
})

const combinedAsArray = css([someMoreBasicStyles, someCssAsObject])

const cls1 = css`
font-size: 20px;
padding: 5px;
background: green;
color: orange;
`
const cls2 = css`
font-size: 20px;
padding: 15px;
background: blue;
color: white;
`

const cxExample = cx(cls1, cls2)

const bounce = keyframes`
from, 20%, 53%, 80%, to {
transform: translate3d(0,0,0);
}

40%, 43% {
transform: translate3d(0, -30px, 0);
}

70% {
transform: translate3d(0, -15px, 0);
}

90% {
transform: translate3d(0,-4px,0);
}
`

const keyframesExample = css([
bounce,
css({
marginTop: '50px',
width: '20px',
height: '20px',
background: 'black',
borderRadius: '50%',
padding: '20px',
animation: `${bounce} 1s ease infinite`,
transformOrigin: 'center',
}),
])

export {
combinedAsArray,
cxExample,
keyframesExample,
someCssAsObject,
someMoreBasicStyles,
otherStyles,
basicStyles,
}