feature/vanilla-emotion - add an example of vanilla emotion (#20228)
Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com> Co-authored-by: Tim Neutkens <tim@timneutkens.nl>
This commit is contained in:
parent
4dc32ec0a7
commit
60b0267400
8 changed files with 260 additions and 0 deletions
4
examples/with-emotion-vanilla/.babelrc
Normal file
4
examples/with-emotion-vanilla/.babelrc
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"presets": [["next/babel"]],
|
||||
"plugins": ["@emotion/babel-plugin"]
|
||||
}
|
34
examples/with-emotion-vanilla/.gitignore
vendored
Normal file
34
examples/with-emotion-vanilla/.gitignore
vendored
Normal file
|
@ -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
examples/with-emotion-vanilla/README.md
Normal file
24
examples/with-emotion-vanilla/README.md
Normal file
|
@ -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
examples/with-emotion-vanilla/package.json
Normal file
20
examples/with-emotion-vanilla/package.json
Normal file
|
@ -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
examples/with-emotion-vanilla/pages/_document.js
Normal file
34
examples/with-emotion-vanilla/pages/_document.js
Normal file
|
@ -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
examples/with-emotion-vanilla/pages/index.js
Normal file
30
examples/with-emotion-vanilla/pages/index.js
Normal file
|
@ -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
examples/with-emotion-vanilla/shared/renderer.js
Normal file
12
examples/with-emotion-vanilla/shared/renderer.js
Normal file
|
@ -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
examples/with-emotion-vanilla/shared/styles.js
Normal file
102
examples/with-emotion-vanilla/shared/styles.js
Normal file
|
@ -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,
|
||||
}
|
Loading…
Reference in a new issue