diff --git a/examples/with-xstate/README.md b/examples/with-xstate/README.md new file mode 100644 index 000000000000000..38367fc0ecfcfe1 --- /dev/null +++ b/examples/with-xstate/README.md @@ -0,0 +1,46 @@ +# XState example + +This example shows how to integrate XState in Next.js. For more info about XState you can visit [here](https://xstate.js.org/). + +## Deploy your own + +Deploy the example using [ZEIT Now](https://zeit.co/now): + +[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/next.js/tree/canary/examples/with-xstate) + +## How to use + +### Using `create-next-app` + +Execute [`create-next-app`](https://github.com/zeit/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 +npm init next-app --example with-xstate with-xstate-app +# or +yarn create next-app --example with-xstate with-xstate-app +``` + +### Download manually + +Download the example: + +```bash +curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/with-xstate +cd with-xstate +``` + +Install it and run: + +```bash +npm install +npm run dev +# or +yarn +yarn dev +``` + +Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download)): + +```bash +now +``` diff --git a/examples/with-xstate/components/Counter.js b/examples/with-xstate/components/Counter.js new file mode 100644 index 000000000000000..10e6b440295f18f --- /dev/null +++ b/examples/with-xstate/components/Counter.js @@ -0,0 +1,10 @@ +export default ({ counter = {} }) => ( +
+

+ Count: {counter.count} +

+ + + +
+) diff --git a/examples/with-xstate/components/Toggle.js b/examples/with-xstate/components/Toggle.js new file mode 100644 index 000000000000000..ce609b97a110827 --- /dev/null +++ b/examples/with-xstate/components/Toggle.js @@ -0,0 +1,14 @@ +import React from 'react' + +const Toggle = ({ onToggle, active }) => { + return ( +
+

+ Toogle status: {active ? 'On' : 'Off'} +

+ +
+ ) +} + +export default Toggle diff --git a/examples/with-xstate/components/index.js b/examples/with-xstate/components/index.js new file mode 100644 index 000000000000000..dd86cb409f508da --- /dev/null +++ b/examples/with-xstate/components/index.js @@ -0,0 +1,4 @@ +import Counter from './Counter' +import Toggle from './Toggle' + +export { Counter, Toggle } diff --git a/examples/with-xstate/machines/counterMachine.js b/examples/with-xstate/machines/counterMachine.js new file mode 100644 index 000000000000000..dac19012736ab37 --- /dev/null +++ b/examples/with-xstate/machines/counterMachine.js @@ -0,0 +1,20 @@ +import { Machine, assign } from 'xstate' + +const increment = context => context.count + 1 +const decrement = context => context.count - 1 + +export const counterMachine = Machine({ + initial: 'active', + context: { + count: 0, + }, + states: { + active: { + on: { + INC: { actions: assign({ count: increment }) }, + DEC: { actions: assign({ count: decrement }) }, + RESET: { actions: assign({ count: 0 }) }, + }, + }, + }, +}) diff --git a/examples/with-xstate/machines/toggleMachine.js b/examples/with-xstate/machines/toggleMachine.js new file mode 100644 index 000000000000000..3c79f27b57523a5 --- /dev/null +++ b/examples/with-xstate/machines/toggleMachine.js @@ -0,0 +1,14 @@ +import { Machine } from 'xstate' + +export const toggleMachine = Machine({ + id: 'toggle', + initial: 'inactive', + states: { + inactive: { + on: { TOGGLE: 'active' }, + }, + active: { + on: { TOGGLE: 'inactive' }, + }, + }, +}) diff --git a/examples/with-xstate/package.json b/examples/with-xstate/package.json new file mode 100644 index 000000000000000..899d59e455a9dc2 --- /dev/null +++ b/examples/with-xstate/package.json @@ -0,0 +1,17 @@ +{ + "name": "with-xstate", + "version": "1.0.0", + "scripts": { + "dev": "next", + "build": "next build", + "start": "next start" + }, + "dependencies": { + "@xstate/react": "0.8.1", + "next": "latest", + "react": "^16.9.0", + "react-dom": "^16.9.0", + "xstate": "4.7.6" + }, + "license": "ISC" +} diff --git a/examples/with-xstate/pages/index.js b/examples/with-xstate/pages/index.js new file mode 100644 index 000000000000000..3e32a3b2cbd1369 --- /dev/null +++ b/examples/with-xstate/pages/index.js @@ -0,0 +1,36 @@ +import React from 'react' +import { useMachine } from '@xstate/react' +import { Counter, Toggle } from '../components' +import { toggleMachine } from '../machines/toggleMachine' +import { counterMachine } from '../machines/counterMachine' + +const IndexPage = ({ count }) => { + const [toggleCurrent, toggleSend] = useMachine(toggleMachine) + const [counterCurrent, counterSend] = useMachine(counterMachine, { + context: { count }, + }) + + return ( +
+ counterSend('INC'), + decrement: () => counterSend('DEC'), + reset: () => counterSend('RESET'), + }} + /> +
+ toggleSend('TOGGLE')} + active={toggleCurrent.matches('active')} + /> +
+ ) +} + +IndexPage.getInitialProps = async () => { + return { count: 999 } +} + +export default IndexPage