Skip to content

Commit 8a9ceb6

Browse files
Merge pull request cerebral#177 from cerebral/moreStuff
More stuff
2 parents 5438ce0 + d4f85eb commit 8a9ceb6

File tree

12 files changed

+682
-4
lines changed

12 files changed

+682
-4
lines changed

packages/node_modules/proxy-state-tree/src/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,15 @@ export class ProxyStateTree<T extends object> implements IProxyStateTree<T> {
121121
}
122122
onMutation(callback: IMutationCallback) {
123123
this.mutationCallbacks.push(callback)
124+
125+
return () =>
126+
this.mutationCallbacks.splice(this.mutationCallbacks.indexOf(callback), 1)
124127
}
125128
onFlush(callback: IFlushCallback) {
126129
this.flushCallbacks.push(callback)
130+
131+
return () =>
132+
this.flushCallbacks.splice(this.flushCallbacks.indexOf(callback), 1)
127133
}
128134
addMutation(mutation: IMutation, objectChangePath?: string) {
129135
this.mutations.push(mutation)

packages/overmind-website/api/connect.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,12 @@
44
h(Example, { name: "api/connect" })
55
```
66

7-
The **connect** function you created is used to connect components to your application. Any state you access in the component is automatically tracked by Overmind and the component will rerender when there is a change.
7+
The **connect** function you created is used to connect components to your application. Any state you access in the component is automatically tracked by Overmind and the component will rerender when there is a change.
8+
9+
## addMutationListener
10+
11+
You also have access to manually react to changes in the state. This gives you a lot of flexibility as you can react to type of change and at what path. You can even pattern match the path to react to nested changes etc.
12+
13+
```marksy
14+
h(Example, { name: "api/connect_listener" })
15+
```
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
const javascript = {
2+
react: [
3+
{
4+
fileName: 'SomeComponent.js',
5+
code: `
6+
import React from 'react'
7+
import { connect } from '../app'
8+
9+
class SomeComponent extends React.Component {
10+
componentDidMount() {
11+
const overmind = this.props.overmind
12+
13+
this.disposeMutationListener = overmind.addMutationListener((mutation) => {
14+
// Check mutation and do something
15+
})
16+
}
17+
componentWillUnmount() {
18+
this.disposeMutationListener()
19+
}
20+
render() {
21+
const overmind = this.props.overmind
22+
23+
return (
24+
<div onClick={overmind.actions.onClick}>
25+
{overmind.state.foo}
26+
</div>
27+
)
28+
}
29+
}
30+
31+
export default connect(SomeComponent)
32+
`,
33+
},
34+
],
35+
vue: [
36+
{
37+
fileName: 'SomeComponent.vue (template)',
38+
code: `
39+
<div v-on:click="overmind.actions.onClick">
40+
{{overmind.state.foo}}
41+
</div>
42+
`,
43+
},
44+
{
45+
fileName: 'SomeComponent.vue (script)',
46+
code: `
47+
import { connect } from '../app'
48+
49+
export default connect({
50+
mounted() {
51+
this.disposeMutationListener = this.overmind.addMutationListener((mutation) => {
52+
// Check mutation and do something
53+
})
54+
},
55+
beforeDestroy() {
56+
this.disposeMutationListener()
57+
}
58+
})
59+
`,
60+
},
61+
],
62+
}
63+
64+
const typescript = {
65+
react: [
66+
{
67+
fileName: 'SomeComponent.tsx',
68+
code: `
69+
import * as React from 'react'
70+
import { connect, Connect } from '../app'
71+
72+
type Props = {} & Connect
73+
74+
class SomeComponent extends React.Component<Props> {
75+
disposeMutationListener: () => void
76+
componentDidMount() {
77+
const overmind = this.props.overmind
78+
79+
this.disposeMutationListener = overmind.addMutationListener((mutation) => {
80+
// Check mutation and do something
81+
})
82+
}
83+
componentWillUnmount() {
84+
this.disposeMutationListener()
85+
}
86+
render() {
87+
const overmind = this.props.overmind
88+
89+
return (
90+
<div onClick={overmind.actions.onClick}>
91+
{overmind.state.foo}
92+
</div>
93+
)
94+
}
95+
}
96+
97+
export default connect(SomeComponent)
98+
`,
99+
},
100+
],
101+
vue: javascript.vue,
102+
angular: [
103+
{
104+
fileName: 'some.component.ts',
105+
code: `
106+
import { Component } from '@angular/core';
107+
import { connect } from '../app'
108+
109+
@Component({
110+
selector: 'some-component',
111+
template: \`
112+
<div (click)="overmind.actions.onClick()">
113+
{{overmind.state.foo}}
114+
</div>
115+
\`
116+
})
117+
@connect()
118+
export class SomeComponent {
119+
disposeMutationListener: () => void
120+
ngOnInit() {
121+
this.disposeMutationListener = this.overmind.addMutationListener((mutation) => {
122+
// Check mutation and do something
123+
})
124+
}
125+
ngOnDestroy() {
126+
this.disposeMutationListener()
127+
}
128+
}
129+
`,
130+
},
131+
],
132+
}
133+
134+
export default (ts, view) => (ts ? typescript[view] : javascript[view])

packages/overmind-website/examples/frontpage/operators.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ export const search = pipe(
55
setQuery,
66
filterValidQuery,
77
debounce(200),
8-
getResult,
9-
catchResultError,
10-
setResult
8+
getSearchResult
119
)
1210
`,
1311
},
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
export default (ts) =>
2+
ts
3+
? [
4+
{
5+
fileName: 'app/index.ts',
6+
code: `
7+
import { Overmind, TConfig } from 'overmind'
8+
import { createConnect, TConnect } from 'overmind-react'
9+
import { state } from './state'
10+
import * as actions from './actions'
11+
12+
const config = {
13+
state,
14+
actions
15+
}
16+
17+
declare module 'overmind' {
18+
interface IConfig extends TConfig<typeof config> {}
19+
}
20+
21+
export type Connect = TConnect<typeof config>
22+
23+
const app = new Overmind(config)
24+
25+
export const connect = createConnect(app)
26+
`,
27+
},
28+
{
29+
fileName: 'components/App.tsx',
30+
code: `
31+
import * as React from 'react'
32+
import { connect, Connect } from '../app'
33+
34+
type Props = {} & Connect
35+
36+
const App: React.SFC<Props> = ({ overmind }) => {
37+
const { state, actions } = overmind
38+
39+
return <div />
40+
}
41+
42+
export default connect(App)
43+
`,
44+
},
45+
]
46+
: [
47+
{
48+
fileName: 'app/index.jsx',
49+
code: `
50+
import { Overmind } from 'overmind'
51+
import { createConnect } from 'overmind-react'
52+
53+
const app = new Overmind({
54+
state: {},
55+
actions: {}
56+
})
57+
58+
export const connect = createConnect(app)
59+
`,
60+
},
61+
{
62+
fileName: 'components/App.jsx',
63+
code: `
64+
import React from 'react'
65+
import { connect } from '../app'
66+
67+
const App = ({ overmind }) => {
68+
const { state, actions } = overmind
69+
70+
return <div />
71+
}
72+
73+
export default connect(App)
74+
`,
75+
},
76+
]
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
export default (ts) =>
2+
ts
3+
? [
4+
{
5+
fileName: 'components/App.tsx',
6+
code: `
7+
import * as React from 'react'
8+
import { connect, Connect } from '../app'
9+
10+
type Props = {} & Connect
11+
12+
class App extends React.Component<Props> {
13+
disposeMutationListener: () => void
14+
componentDidMount() {
15+
this.disposeMutationListener = this.props.overmind.addMutationListener((mutation) => {
16+
if (mutation.path === 'currentPage') {
17+
document.querySelector('#app').scrollTop = 0
18+
}
19+
})
20+
}
21+
componentWillUnmount() {
22+
this.disposeMutationListener()
23+
}
24+
render() {
25+
const { state, actions } = this.props.overmind
26+
27+
return <div />
28+
}
29+
}
30+
31+
export default connect(App)
32+
`,
33+
},
34+
]
35+
: [
36+
{
37+
fileName: 'components/App.jsx',
38+
code: `
39+
import React from 'react'
40+
import { connect } from '../app'
41+
42+
class App extends React.Component {
43+
componentDidMount() {
44+
this.disposeMutationListener = this.props.overmind.addMutationListener((mutation) => {
45+
if (mutation.path.includes('currentPage')) {
46+
document.querySelector('#app').scrollTop = 0
47+
}
48+
})
49+
}
50+
componentWillUnmount() {
51+
this.disposeMutationListener()
52+
}
53+
render() {
54+
const { state, actions } = this.props.overmind
55+
56+
return <div />
57+
}
58+
}
59+
60+
export default connect(App)
61+
`,
62+
},
63+
]
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
export default (ts) =>
2+
ts
3+
? [
4+
{
5+
fileName: 'components/Todos.tsx',
6+
code: `
7+
import * as React from 'react'
8+
import { connect, Connect } from '../app'
9+
import Todo from './Todo'
10+
11+
type Props = {} & Connect
12+
13+
const Todos: React.SFC<Props> = ({ overmind }) => {
14+
const { state } = overmind
15+
16+
return (
17+
<ul>
18+
{state.todos.map(todo => <Todo key={todo.id} todo={todo} />)}
19+
</ul<
20+
)
21+
}
22+
23+
export default connect(Todos)
24+
`,
25+
},
26+
{
27+
fileName: 'components/Todo.tsx',
28+
code: `
29+
import * as React from 'react'
30+
import { connect, Connect } from '../app'
31+
32+
type Props = {
33+
todo: Todo
34+
} & Connect
35+
36+
const Todo: React.SFC<Props> = ({ todo }) => {
37+
return <li>{todo.title}</li>
38+
}
39+
40+
export default connect(Todo)
41+
`,
42+
},
43+
]
44+
: [
45+
{
46+
fileName: 'components/Todos.jsx',
47+
code: `
48+
import React from 'react'
49+
import { connect } from '../app'
50+
import Todo from './Todo'
51+
52+
const Todos = ({ overmind }) => {
53+
const { state } = overmind
54+
55+
return (
56+
<ul>
57+
{state.todos.map(todo => <Todo key={todo.id} todo={todo} />)}
58+
</ul<
59+
)
60+
}
61+
62+
export default connect(Todos)
63+
`,
64+
},
65+
{
66+
fileName: 'components/Todo.jsx',
67+
code: `
68+
import React from 'react'
69+
import { connect } from '../app'
70+
71+
const Todo = ({ todo }) => {
72+
return <li>{todo.title}</li>
73+
}
74+
75+
export default connect(Todo)
76+
`,
77+
},
78+
]

0 commit comments

Comments
 (0)