mirror of
https://github.com/terribleplan/next.js.git
synced 2024-01-19 02:48:18 +00:00
Add with Portals example (#3372)
This commit is contained in:
parent
01f05d8cbc
commit
32eb6b7718
27
examples/with-portals/README.md
Normal file
27
examples/with-portals/README.md
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
# Example with portals
|
||||||
|
|
||||||
|
## How to use
|
||||||
|
|
||||||
|
Download the example [or clone the repo](https://github.com/zeit/next.js):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/with-portals
|
||||||
|
cd with-portals
|
||||||
|
```
|
||||||
|
|
||||||
|
Install it and run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download))
|
||||||
|
|
||||||
|
```bash
|
||||||
|
now
|
||||||
|
```
|
||||||
|
|
||||||
|
## The idea behind the example
|
||||||
|
|
||||||
|
This example show how to use the React [Portals](https://reactjs.org/docs/portals.html) feature with Next.js.
|
50
examples/with-portals/components/modal.js
Normal file
50
examples/with-portals/components/modal.js
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
import { Component } from 'react'
|
||||||
|
import { createPortal } from 'react-dom'
|
||||||
|
|
||||||
|
export default class extends Component {
|
||||||
|
componentWillMount () {
|
||||||
|
// get the mount point, is because of this why the modal
|
||||||
|
// can't be used server side, we need access to the DOM
|
||||||
|
this.modalRoot = document.getElementById('modal')
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const { title, children } = this.props
|
||||||
|
|
||||||
|
return createPortal(
|
||||||
|
<div className='overlay'>
|
||||||
|
<div className='modal'>
|
||||||
|
<h2>{title}</h2>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
<style jsx global>{`
|
||||||
|
body {
|
||||||
|
/* this avoid any possible scroll on the body */
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
`}</style>
|
||||||
|
<style jsx>{`
|
||||||
|
.overlay {
|
||||||
|
position: fixed;
|
||||||
|
background-color: rgba(0, 0, 0, .7);
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal {
|
||||||
|
background-color: white;
|
||||||
|
position: absolute;
|
||||||
|
top: 10%;
|
||||||
|
right: 10%;
|
||||||
|
bottom: 10%;
|
||||||
|
left: 10%;
|
||||||
|
padding: 1em;
|
||||||
|
}
|
||||||
|
`}</style>
|
||||||
|
</div>,
|
||||||
|
this.modalRoot
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
12
examples/with-portals/package.json
Normal file
12
examples/with-portals/package.json
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"dev": "next",
|
||||||
|
"build": "next build",
|
||||||
|
"start": "next start"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"next": "^4.1.4",
|
||||||
|
"react": "^16.2.0",
|
||||||
|
"react-dom": "^16.2.0"
|
||||||
|
}
|
||||||
|
}
|
17
examples/with-portals/pages/_document.js
Normal file
17
examples/with-portals/pages/_document.js
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import Document, { Head, Main, NextScript } from 'next/document'
|
||||||
|
|
||||||
|
export default class extends Document {
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<html>
|
||||||
|
<Head />
|
||||||
|
<body>
|
||||||
|
<Main />
|
||||||
|
{/* here we will mount our modal portal */}
|
||||||
|
<div id='modal' />
|
||||||
|
<NextScript />
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
31
examples/with-portals/pages/index.js
Normal file
31
examples/with-portals/pages/index.js
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
import { Component } from 'react'
|
||||||
|
import dynamic from 'next/dynamic'
|
||||||
|
|
||||||
|
// we import and render the modal only client side (because we need a DOM)
|
||||||
|
const Modal = dynamic(import('../components/modal'), {
|
||||||
|
ssr: false
|
||||||
|
})
|
||||||
|
|
||||||
|
export default class extends Component {
|
||||||
|
state = { modal: false };
|
||||||
|
|
||||||
|
toggleModal = () => this.setState(state => ({ modal: !state.modal }))
|
||||||
|
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<main>
|
||||||
|
<button type='button' onClick={this.toggleModal}>
|
||||||
|
Open modal
|
||||||
|
</button>
|
||||||
|
{this.state.modal && (
|
||||||
|
<Modal title='My Modal Portal'>
|
||||||
|
<p>This is a portal rendered from Next.js</p>
|
||||||
|
<button type='button' onClick={this.toggleModal}>
|
||||||
|
Close
|
||||||
|
</button>
|
||||||
|
</Modal>
|
||||||
|
)}
|
||||||
|
</main>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue