diff --git a/examples/with-next-page-transitions/README.md b/examples/with-next-page-transitions/README.md new file mode 100644 index 00000000..e34ba890 --- /dev/null +++ b/examples/with-next-page-transitions/README.md @@ -0,0 +1,45 @@ +[![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-next-page-transitions) + +# next-page-transitions example + +## How to use + +### Using `create-next-app` + +Execute [`create-next-app`](https://github.com/segmentio/create-next-app) with [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) or [npx](https://github.com/zkat/npx#readme) to bootstrap the example: + +```bash +npx create-next-app --example with-next-page-transitions with-next-page-transitions +# or +yarn create next-app --example with-next-page-transitions with-next-page-transitions +``` + +### Download manually + +Download the example [or clone the repo](https://github.com/zeit/next.js): + +```bash +curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/with-next-page-transitions +cd with-next-page-transitions +``` + +Install it and run: + +```bash +npm install +npm run build +npm start +``` + +Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download)) + +```bash +now +``` + +## The idea behind the example + +The [`next-page-transitions`](https://github.com/illinois/next-page-transitions) library is a component that sits at the app level and allows you to animate page changes. It works especially nicely with apps with a shared layout element, like a navbar. This component will ensure that only one page is ever mounted at a time, and manages the timing of animations for you. This component works similarly to [`react-transition-group`](https://github.com/reactjs/react-transition-group) in that it applies classes to a container around your page; it's up to you to write the CSS transitions or animations to make things pretty! + +This example includes two pages with links between them. The "About" page demonstrates how `next-page-transitions` makes it easy to add a loading state when navigating to a page: it will wait for the page to "load" its content (in this examples, that's simulated with a timeout) and then hide the loading indicator and animate in the page when it's done. + diff --git a/examples/with-next-page-transitions/components/Loader.js b/examples/with-next-page-transitions/components/Loader.js new file mode 100644 index 00000000..f5f96a72 --- /dev/null +++ b/examples/with-next-page-transitions/components/Loader.js @@ -0,0 +1,30 @@ +import React from 'react' + +const Loader = () => ( +
+ +
+) + +export default Loader diff --git a/examples/with-next-page-transitions/package.json b/examples/with-next-page-transitions/package.json new file mode 100644 index 00000000..83f77a91 --- /dev/null +++ b/examples/with-next-page-transitions/package.json @@ -0,0 +1,16 @@ +{ + "name": "with-next-page-transitions", + "version": "1.0.0", + "scripts": { + "dev": "next", + "build": "next build", + "start": "next start" + }, + "dependencies": { + "next": "latest", + "react": "^16.0.0", + "react-dom": "^16.0.0", + "next-page-transitions": "1.0.0-alpha.2" + }, + "license": "ISC" +} diff --git a/examples/with-next-page-transitions/pages/_app.js b/examples/with-next-page-transitions/pages/_app.js new file mode 100644 index 00000000..36ee6d6b --- /dev/null +++ b/examples/with-next-page-transitions/pages/_app.js @@ -0,0 +1,67 @@ +import React from 'react' +import App, { Container } from 'next/app' +import { PageTransition } from 'next-page-transitions' + +import Loader from '../components/Loader' + +const TIMEOUT = 400 + +export default class MyApp extends App { + static async getInitialProps ({ Component, ctx }) { + let pageProps = {} + + if (Component.getInitialProps) { + pageProps = await Component.getInitialProps(ctx) + } + + return { pageProps } + } + + render () { + const { Component, pageProps } = this.props + return ( + + } + loadingDelay={500} + loadingTimeout={{ + enter: TIMEOUT, + exit: 0 + }} + loadingClassNames='loading-indicator' + > + + + + + ) + } +} diff --git a/examples/with-next-page-transitions/pages/_document.js b/examples/with-next-page-transitions/pages/_document.js new file mode 100644 index 00000000..25e85520 --- /dev/null +++ b/examples/with-next-page-transitions/pages/_document.js @@ -0,0 +1,37 @@ +import React from 'react' +import Document, { Head, Main, NextScript } from 'next/document' + +export default class MyDocument extends Document { + static async getInitialProps (ctx) { + const initialProps = await Document.getInitialProps(ctx) + return { ...initialProps } + } + + render () { + return ( + + + + + + + +
+ + + + ) + } +} diff --git a/examples/with-next-page-transitions/pages/about.js b/examples/with-next-page-transitions/pages/about.js new file mode 100644 index 00000000..3d6a1021 --- /dev/null +++ b/examples/with-next-page-transitions/pages/about.js @@ -0,0 +1,51 @@ +import React from 'react' +import PropTypes from 'prop-types' +import Link from 'next/link' + +class About extends React.Component { + static pageTransitionDelayEnter = true + + constructor (props) { + super(props) + this.state = { + loaded: false + } + } + + componentDidMount () { + this.timeoutId = setTimeout(() => { + this.props.pageTransitionReadyToEnter() + this.setState({ loaded: true }) + }, 2000) + } + + componentWillUnmount () { + if (this.timeoutId) clearTimeout(this.timeoutId) + } + + render () { + if (!this.state.loaded) return null + return ( +
+

About us

+

+ Notice how a loading spinner showed up while my content was "loading"? + Pretty neat, huh? +

+ + Go back home + +
+ ) + } +} + +About.propTypes = { + pageTransitionReadyToEnter: PropTypes.func +} + +About.defaultProps = { + pageTransitionReadyToEnter: () => {} +} + +export default About diff --git a/examples/with-next-page-transitions/pages/index.js b/examples/with-next-page-transitions/pages/index.js new file mode 100644 index 00000000..d4dcf1fc --- /dev/null +++ b/examples/with-next-page-transitions/pages/index.js @@ -0,0 +1,13 @@ +import React from 'react' +import Link from 'next/link' + +const Index = () => ( +
+

Hello, world!

+ + About us + +
+) + +export default Index