-
Notifications
You must be signed in to change notification settings - Fork 3
/
hashrouter.html
69 lines (59 loc) · 2.19 KB
/
hashrouter.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
<h1>Minimalist Hash Routing with Surplus</h1>
<script type="text/jsx">
// Super-simple hash-based router
// "#!foo/bar/1" runs the 'foo' route from the table, passing it the params ["bar", "1"]
// See the end of this file for an example usage.
const HashRouter = routes => {
const
// data signal to track the state of window.location.hash
hash = S.data(window.location.hash),
// and a function to update it
updateHash = () => hash(window.location.hash),
// computation to find the route for the current hash and call it, constructing the current view
view = S(() => {
// convert the hash to a path by removing #! and splitting on '/', so '#!item/1' becomes ["item", "1"]
const path = hash().replace(/^#?!?/, '').split(/\//);
if (!(path[0] in routes)) return <div>No route matches {path[0]}</div>;
return routes[path[0]](path.slice(1));
});
// make router live by subscribing to hash changes
window.addEventListener('hashchange', updateHash);
S.cleanup(() => window.removeEventListener('hashchange', updateHash));
return { view };
};
// now build a dummy app to demo the router
// some data
const items = [
{ id: 1, name : "foo"},
{ id: 2, name: "bar" },
{ id: 3, name: "baz" }
];
// some components
const
// a clickable list of items
Index = ({items}) =>
<ul>{items.map(item =>
<li><a href={`#!item/${item.id}`}>Go to {item.name}</a></li>
)}</ul>,
// a single item with a return link
Item = ({item}) =>
<div>
<h3>You clicked on {item.name} (item #{item.id})</h3>
<a href="#!">Go back to index</a>
</div>;
// our routing table
const routes = {
// empty hash (default) displays the Index
'': () => <Index items={items} />,
// '#!item/id' displays Item
item: ([id]) => <Item item={items.find(item => item.id === +id)} />
};
// build our router and append the view into the page
S.root(() => {
const router = HashRouter(routes);
document.body.appendChild(
<div className="app">{router.view()}</div>
);
});
</script>
<script src="https://unpkg.com/surplus-toys"></script>