mirror of
https://github.com/terribleplan/next.js.git
synced 2024-01-19 02:48:18 +00:00
Add Cerebral example (#2976)
This commit is contained in:
parent
4bd30c8713
commit
094bb1f7b9
24
examples/with-cerebral/components/Clock.js
Normal file
24
examples/with-cerebral/components/Clock.js
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
export default (props) => {
|
||||||
|
return (
|
||||||
|
<div className={props.light ? 'light' : ''}>
|
||||||
|
{format(new Date(props.lastUpdate))}
|
||||||
|
<style jsx>{`
|
||||||
|
div {
|
||||||
|
padding: 15px;
|
||||||
|
color: #82FA58;
|
||||||
|
display: inline-block;
|
||||||
|
font: 50px menlo, monaco, monospace;
|
||||||
|
background-color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.light {
|
||||||
|
background-color: #999;
|
||||||
|
}
|
||||||
|
`}</style>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const format = t => `${pad(t.getUTCHours())}:${pad(t.getUTCMinutes())}:${pad(t.getUTCSeconds())}`
|
||||||
|
|
||||||
|
const pad = n => n < 10 ? `0${n}` : n
|
33
examples/with-cerebral/components/Page.js
Normal file
33
examples/with-cerebral/components/Page.js
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
import React from 'react'
|
||||||
|
import Link from 'next/link'
|
||||||
|
import { connect } from '@cerebral/react'
|
||||||
|
import { state, signal } from 'cerebral/tags'
|
||||||
|
import Clock from './Clock'
|
||||||
|
|
||||||
|
export default connect({
|
||||||
|
lastUpdate: state`clock.lastUpdate`,
|
||||||
|
light: state`clock.light`,
|
||||||
|
mounted: signal`clock.mounted`,
|
||||||
|
unMounted: signal`clock.unMounted`
|
||||||
|
},
|
||||||
|
class Page extends React.Component {
|
||||||
|
componentDidMount () {
|
||||||
|
this.props.mounted()
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount () {
|
||||||
|
this.props.unMounted()
|
||||||
|
}
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1>{this.props.title}</h1>
|
||||||
|
<Clock lastUpdate={this.props.lastUpdate} light={this.props.light} />
|
||||||
|
<nav>
|
||||||
|
<Link href={this.props.linkTo}><a>Navigate</a></Link>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
7
examples/with-cerebral/modules/clock/actions.js
Normal file
7
examples/with-cerebral/modules/clock/actions.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
export function startTimer ({clock}) {
|
||||||
|
clock.start('clock.secondTicked')
|
||||||
|
}
|
||||||
|
|
||||||
|
export function stopTimer ({clock}) {
|
||||||
|
clock.stop()
|
||||||
|
}
|
16
examples/with-cerebral/modules/clock/index.js
Normal file
16
examples/with-cerebral/modules/clock/index.js
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
import {mounted, unMounted, secondTicked} from './signals'
|
||||||
|
import provider from './provider'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
state: {
|
||||||
|
lastUpdate: 0,
|
||||||
|
light: false
|
||||||
|
},
|
||||||
|
signals: {
|
||||||
|
mounted,
|
||||||
|
unMounted,
|
||||||
|
secondTicked
|
||||||
|
},
|
||||||
|
provider
|
||||||
|
}
|
26
examples/with-cerebral/modules/clock/provider.js
Normal file
26
examples/with-cerebral/modules/clock/provider.js
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
// milliseconds per second
|
||||||
|
const SECOND = 1000
|
||||||
|
let timer = null
|
||||||
|
|
||||||
|
export default (context) => {
|
||||||
|
context.clock = {
|
||||||
|
start (signalPath) {
|
||||||
|
const signal = context.controller.getSignal(signalPath)
|
||||||
|
|
||||||
|
function tick () {
|
||||||
|
const now = Date.now()
|
||||||
|
|
||||||
|
signal({now})
|
||||||
|
|
||||||
|
timer = setTimeout(tick, SECOND - (now % SECOND))
|
||||||
|
}
|
||||||
|
|
||||||
|
tick()
|
||||||
|
},
|
||||||
|
stop () {
|
||||||
|
clearTimeout(timer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return context
|
||||||
|
}
|
10
examples/with-cerebral/modules/clock/signals.js
Normal file
10
examples/with-cerebral/modules/clock/signals.js
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import {set} from 'cerebral/operators'
|
||||||
|
import {state, props} from 'cerebral/tags'
|
||||||
|
import {startTimer, stopTimer} from './actions'
|
||||||
|
|
||||||
|
export const mounted = [
|
||||||
|
startTimer,
|
||||||
|
set(state`clock.light`, true)
|
||||||
|
]
|
||||||
|
export const unMounted = stopTimer
|
||||||
|
export const secondTicked = set(state`clock.lastUpdate`, props`now`)
|
18
examples/with-cerebral/package.json
Normal file
18
examples/with-cerebral/package.json
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"name": "with-cerebral",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "next",
|
||||||
|
"build": "next build",
|
||||||
|
"start": "next start"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"@cerebral/react": "^2.1.0",
|
||||||
|
"cerebral": "^3.1.0",
|
||||||
|
"next": "^3.2.2"
|
||||||
|
}
|
||||||
|
}
|
42
examples/with-cerebral/pages/index.js
Normal file
42
examples/with-cerebral/pages/index.js
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
import React from 'react'
|
||||||
|
import {Controller, UniversalController} from 'cerebral'
|
||||||
|
import Devtools from 'cerebral/devtools'
|
||||||
|
import { Container } from '@cerebral/react'
|
||||||
|
import Page from '../components/Page'
|
||||||
|
import clock from '../modules/clock'
|
||||||
|
|
||||||
|
export default class Counter extends React.Component {
|
||||||
|
static getInitialProps ({req}) {
|
||||||
|
const isServer = Boolean(req)
|
||||||
|
|
||||||
|
// On the server we prepare the state of the application. Since
|
||||||
|
// this is a synchronous state change we just use "setState", but
|
||||||
|
// you could do other async stuff here or even use "runSequence" to
|
||||||
|
// grab and set the initial state of the application using
|
||||||
|
if (isServer) {
|
||||||
|
const controller = UniversalController({modules: {clock}})
|
||||||
|
controller.setState('clock.lastUpdate', Date.now())
|
||||||
|
|
||||||
|
return { stateChanges: controller.getChanges() }
|
||||||
|
}
|
||||||
|
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
constructor (props) {
|
||||||
|
super(props)
|
||||||
|
// The controller will be instantiated for every page change and we only
|
||||||
|
// add the devtools if we indeed are running in the browser
|
||||||
|
this.controller = Controller({
|
||||||
|
devtools: process.env.NODE_ENV === 'production' || typeof window === 'undefined' ? null : Devtools({host: 'localhost:8787'}),
|
||||||
|
modules: {clock},
|
||||||
|
stateChanges: props.stateChanges
|
||||||
|
})
|
||||||
|
}
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<Container controller={this.controller}>
|
||||||
|
<Page title='Index Page' linkTo='/other' />
|
||||||
|
</Container>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
42
examples/with-cerebral/pages/other.js
Normal file
42
examples/with-cerebral/pages/other.js
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
import React from 'react'
|
||||||
|
import {Controller, UniversalController} from 'cerebral'
|
||||||
|
import Devtools from 'cerebral/devtools'
|
||||||
|
import { Container } from '@cerebral/react'
|
||||||
|
import Page from '../components/Page'
|
||||||
|
import clock from '../modules/clock'
|
||||||
|
|
||||||
|
export default class Counter extends React.Component {
|
||||||
|
static getInitialProps ({req}) {
|
||||||
|
const isServer = Boolean(req)
|
||||||
|
|
||||||
|
// On the server we prepare the state of the application. Since
|
||||||
|
// this is a synchronous state change we just use "setState", but
|
||||||
|
// you could do other async stuff here or even use "runSequence" to
|
||||||
|
// grab and set the initial state of the application using
|
||||||
|
if (isServer) {
|
||||||
|
const controller = UniversalController({modules: {clock}})
|
||||||
|
controller.setState('clock.lastUpdate', Date.now())
|
||||||
|
|
||||||
|
return { stateChanges: controller.getChanges() }
|
||||||
|
}
|
||||||
|
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
constructor (props) {
|
||||||
|
super(props)
|
||||||
|
// The controller will be instantiated for every page change and we only
|
||||||
|
// add the devtools if we indeed are running in the browser
|
||||||
|
this.controller = Controller({
|
||||||
|
devtools: process.env.NODE_ENV === 'production' || typeof window === 'undefined' ? null : Devtools({host: 'localhost:8787'}),
|
||||||
|
modules: {clock},
|
||||||
|
stateChanges: props.stateChanges
|
||||||
|
})
|
||||||
|
}
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<Container controller={this.controller}>
|
||||||
|
<Page title='Other Page' linkTo='/' />
|
||||||
|
</Container>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue