Skip to content

Commit 987de78

Browse files
committed
first
0 parents commit 987de78

File tree

7 files changed

+39876
-0
lines changed

7 files changed

+39876
-0
lines changed

app.js

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
/** @jsx React.DOM */
2+
3+
function pushUrl(path) {
4+
location.hash = path;
5+
}
6+
7+
function toArray(maybeArray) {
8+
return Array.isArray(maybeArray) ? maybeArray : [maybeArray];
9+
}
10+
11+
function childrenArray(component) {
12+
return component.props.children ? toArray(component.props.children) : [];
13+
}
14+
15+
function matchedChildRoute(path, component) {
16+
var children = childrenArray(component);
17+
for (var i = 0, l = children.length; i < l; i ++) {
18+
if (children[i].props.path === path) {
19+
return children[i];
20+
}
21+
}
22+
return false;
23+
}
24+
25+
var Link = React.createClass({
26+
handleClick: function(event) {
27+
event.preventDefault();
28+
var path = this.props.to;
29+
pushUrl(path);
30+
},
31+
32+
render: function() {
33+
return (
34+
<a href={this.props.to} onClick={this.handleClick}>{this.props.children}</a>
35+
);
36+
}
37+
});
38+
39+
var Routed = {
40+
41+
getInitialState: function() {
42+
return {activeChild: null};
43+
},
44+
45+
componentWillMount: function(path) {
46+
window.addEventListener('hashchange', this.handleRouteChange, false);
47+
this.handleRouteChange();
48+
},
49+
50+
componentWillUnmount: function() {
51+
window.removeEventListener('hashchange', this.handleRouteChange);
52+
},
53+
54+
handleRouteChange: function() {
55+
var path = location.hash.substr(1);
56+
var matched = matchedChildRoute(path, this)
57+
this.setState({activeChild: matched});
58+
},
59+
60+
outlet: function() {
61+
var children = this.props.children;
62+
if (!children) throw new Error("you don't have any children, why are you calling outlet()?");
63+
return this.state.activeChild;
64+
}
65+
66+
};
67+
68+
var App = React.createClass({
69+
mixins: [Routed],
70+
71+
render: function() {
72+
return (
73+
<Root path="/">
74+
<About path="/about"/>
75+
<Users path="/users"/>
76+
</Root>
77+
);
78+
}
79+
});
80+
81+
var Root = React.createClass({
82+
mixins: [Routed],
83+
84+
render: function() {
85+
return (
86+
<div className="Root">
87+
<ul>
88+
<li><Link to="/">Home</Link></li>
89+
<li><Link to="/about">About</Link></li>
90+
<li><Link to="/users">Users</Link></li>
91+
</ul>
92+
{this.outlet()}
93+
</div>
94+
);
95+
}
96+
});
97+
98+
var About = React.createClass({
99+
mixins: [Routed],
100+
101+
render: function() {
102+
return <div className="About"><h1>About</h1></div>;
103+
}
104+
});
105+
106+
var Users = React.createClass({
107+
mixins: [Routed],
108+
109+
statics: {
110+
cache: null
111+
},
112+
113+
getInitialState: function() {
114+
return {users: Users.cache || []};
115+
},
116+
117+
componentDidMount: function() {
118+
var url = 'http://addressbook-api.herokuapp.com/contacts';
119+
if (!Users.cache) {
120+
$.getJSON(url).then(function(res) {
121+
Users.cache = res.contacts;
122+
this.setState({users: res.contacts});
123+
}.bind(this));
124+
}
125+
},
126+
127+
render: function() {
128+
var users = this.state.users.map(function(user) {
129+
return <div>{user.first} {user.last}</div>;
130+
});
131+
var content = !users.length ? 'Loading users...' : users;
132+
return <div className="Users">{content}</div>;
133+
}
134+
});
135+
136+
var User = React.createClass({
137+
mixins: [Routed],
138+
139+
componentDidMount: function() {
140+
if (this.props.user) {
141+
this.setState({user: user});
142+
} else {
143+
$.getJSON('/users/'+this.params.id).then(function(user) {
144+
this.setState({user: user});
145+
}.bind(this));
146+
}
147+
},
148+
149+
render: function() {
150+
var use = this.state.user;
151+
return (
152+
<div className="User">
153+
<h1>{user.name}</h1>
154+
<nav>
155+
<Link to="UserIndex">User</Link>
156+
<Link to="UserAbout" user={user}>About</Link>
157+
</nav>
158+
{this.props.children}
159+
</div>
160+
);
161+
}
162+
});
163+
164+
var UserIndex = React.createClass({
165+
mixins: [Routed],
166+
167+
render: function() {
168+
return <div className="UserIndex"><h2>User Index</h2></div>
169+
}
170+
});
171+
172+
var UserAbout = React.createClass({
173+
mixins: [Routed],
174+
175+
render: function() {
176+
var user = this.props.user;
177+
return (
178+
<div className="UserIndex">
179+
<h2>About {user.name}</h2>
180+
<div>{user.description}</div>
181+
</div>
182+
);
183+
}
184+
});
185+
186+
React.renderComponent(<App/>, document.body);
187+
188+

demo.js

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
/** @jsx React.DOM */
2+
3+
function pushUrl(path) {
4+
location.hash = path;
5+
}
6+
7+
function toArray(maybeArray) {
8+
return Array.isArray(maybeArray) ? maybeArray : [maybeArray];
9+
}
10+
11+
function childrenArray(component) {
12+
return component.props.children ? toArray(component.props.children) : [];
13+
}
14+
15+
function matchedChildRoute(path, component) {
16+
var children = childrenArray(component);
17+
for (var i = 0, l = children.length; i < l; i ++) {
18+
if (children[i].props.path === path) {
19+
return children[i];
20+
}
21+
}
22+
return false;
23+
}
24+
25+
var Link = React.createClass({
26+
handleClick: function(event) {
27+
event.preventDefault();
28+
var path = this.props.to;
29+
pushUrl(path);
30+
},
31+
32+
render: function() {
33+
return (
34+
<a href={this.props.to} onClick={this.handleClick}>{this.props.children}</a>
35+
);
36+
}
37+
});
38+
39+
var Routed = {
40+
41+
getInitialState: function() {
42+
return {activeChild: null};
43+
},
44+
45+
componentWillMount: function(path) {
46+
this.handleRouteChange();
47+
window.addEventListener('hashchange', this.handleRouteChange, false);
48+
},
49+
50+
componentWillUnmount: function() {
51+
window.removeEventListener('hashchange', this.handleRouteChange);
52+
},
53+
54+
handleRouteChange: function() {
55+
var path = location.hash.substr(1);
56+
var matched = matchedChildRoute(path, this)
57+
this.setState({activeChild: matched});
58+
},
59+
60+
outlet: function() {
61+
var children = this.props.children;
62+
if (!children) throw new Error("you don't have any children, why are you calling outlet()?");
63+
return this.state.activeChild;
64+
}
65+
66+
};
67+
68+
/******************************************/
69+
// app stuff
70+
71+
var App = React.createClass({
72+
mixins: [Routed],
73+
74+
render: function() {
75+
return (
76+
<Root path="/">
77+
<About path="/about">
78+
<Company path="/about/company"/>
79+
<Contact path="/contact"/>
80+
</About>
81+
<Users path="/users"/>
82+
</Root>
83+
);
84+
}
85+
});
86+
87+
var Root = React.createClass({
88+
mixins: [Routed],
89+
90+
render: function() {
91+
return (
92+
<div className="Root">
93+
<ul>
94+
<li><Link to="/">Home</Link></li>
95+
<li><Link to="/about">About</Link></li>
96+
<li><Link to="/users">Users</Link></li>
97+
</ul>
98+
{this.outlet()}
99+
</div>
100+
);
101+
}
102+
});
103+
104+
var About = React.createClass({
105+
mixins: [Routed],
106+
render: function() {
107+
return (
108+
<div className="About">
109+
<h1>About</h1>
110+
<ul>
111+
<li><Link to="/about/company">Company</Link></li>
112+
<li><Link to="/contact">Contact</Link></li>
113+
</ul>
114+
{this.outlet()}
115+
</div>
116+
);
117+
}
118+
});
119+
120+
var Company = React.createClass({
121+
mixins: [Routed],
122+
render: function() {
123+
return <div className="Company"><h2>Company</h2></div>;
124+
}
125+
});
126+
127+
var Contact = React.createClass({
128+
mixins: [Routed],
129+
render: function() {
130+
return <div className="About"><h2>Contact</h2></div>;
131+
}
132+
});
133+
134+
var Users = React.createClass({
135+
mixins: [Routed],
136+
137+
statics: {
138+
cache: null
139+
},
140+
141+
getInitialState: function() {
142+
return {users: Users.cache || []};
143+
},
144+
145+
componentDidMount: function() {
146+
var url = 'http://addressbook-api.herokuapp.com/contacts';
147+
if (!Users.cache) {
148+
$.getJSON(url).then(function(res) {
149+
Users.cache = res.contacts;
150+
this.setState({users: res.contacts});
151+
}.bind(this));
152+
}
153+
},
154+
155+
render: function() {
156+
var users = this.state.users.map(function(user) {
157+
return <div>{user.first} {user.last}</div>;
158+
});
159+
var content = !users.length ? 'Loading users...' : users;
160+
return <div className="Users">{content}</div>;
161+
}
162+
});
163+
164+
React.renderComponent(<h1>hello?</h1>, document.body);
165+
166+

index.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<!doctype html public "embarassment">
2+
<title>REACT!</title>
3+
<link rel="stylesheet" href="app.css"/>
4+
<script src="vendor/jquery.js"></script>
5+
<script src="vendor/react.js"></script>
6+
<script src="vendor/JSXTransformer.js"></script>
7+
<script type="text/jsx" src="app.js"></script>
8+
9+

0 commit comments

Comments
 (0)