-
Notifications
You must be signed in to change notification settings - Fork 3
/
main.tsx
104 lines (87 loc) · 2.22 KB
/
main.tsx
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import {IRouteService, MemoryHistory, RouteMatch, Router} from 'boring-router';
import {observable} from 'mobx';
import {observer} from 'mobx-react';
import React, {Component, ReactNode} from 'react';
import ReactDOM from 'react-dom';
import {Link, Route} from '../../bld/library';
const history = new MemoryHistory();
class Account {
constructor(readonly id: string) {}
get avatarURL(): string {
return `https://gravatar.com/avatar/${this.id}`;
}
}
const router = new Router(history);
const route = router.$route({
default: {
$match: '',
},
account: {
$children: {
id: {
$match: RouteMatch.segment,
$extension: {
tick: undefined! as number,
account: undefined! as Account,
},
},
},
},
profile: true,
notFound: {
$match: RouteMatch.rest,
},
});
type AccountIdRouteMatch = typeof route.account.id;
class AccountIdRouteService implements IRouteService<AccountIdRouteMatch> {
private timer!: number;
@observable
tick!: number;
constructor(private match: AccountIdRouteMatch) {}
get account(): Account {
let {id} = this.match.$params;
return new Account(id);
}
beforeEnter(): void {
this.tick = 0;
this.timer = setInterval(() => {
this.tick++;
}, 1000) as any;
}
afterLeave(): void {
clearInterval(this.timer);
}
}
route.account.id.$service(match => new AccountIdRouteService(match));
@observer
export class App extends Component {
render(): ReactNode {
return (
<>
<h1>Boring Router</h1>
<Route match={route.default}>
<p>Home page</p>
<Link
to={route.account.id}
params={{id: '4a35d104523ef520dd5d9f60c7e1eeb1'}}
>
Account
</Link>
</Route>
<Route match={route.account.id}>
{({account, tick}) => (
<>
<p>Account page</p>
<Link to={route.default}>Home</Link>
<hr />
<p>Account {account.id}</p>
<img src={account.avatarURL} alt="avatar" />
<p>Tick {tick}</p>
</>
)}
</Route>
</>
);
}
}
ReactDOM.render(<App />, document.getElementById('app'));