forked from lichess-org/lila
-
Notifications
You must be signed in to change notification settings - Fork 0
/
setting.ts
49 lines (43 loc) · 1.1 KB
/
setting.ts
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
import { h } from 'snabbdom'
import { VNode } from 'snabbdom/vnode'
export interface Setting<A> {
choices: Choices<A>
get(): A
set(v: A): A
}
type Choice<A> = [A, string];
type Choices<A> = Array<Choice<A>>;
interface Opts<A> {
choices: Choices<A>
default: A
storage: LichessStorage
}
export function makeSetting<A>(opts: Opts<A>): Setting<A> {
return {
choices: opts.choices,
get: () => cast<A>(opts.storage.get()) || opts.default,
set(v: A) { opts.storage.set(cast<string>(v)); return v; }
}
}
export function renderSetting<A>(setting: Setting<A>, redraw: () => void): VNode {
const v = setting.get();
return h('select', {
hook: {
insert(vnode) {
(vnode.elm as HTMLSelectElement).addEventListener('change', e => {
setting.set(cast<A>((e.target as HTMLSelectElement).value));
redraw();
});
}
}
}, setting.choices.map(choice => {
const [key, name] = choice;
return h('option', {
attrs: {
value: '' + key,
selected: key === v
}
}, name)
}));
}
function cast<T>(v: any): T { return v; }