aboutsummaryrefslogtreecommitdiff
path: root/src/view/form.ts
blob: 5547e0cffe5d81c260ce98c072f3fabcbbaedd8f (plain)
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import { h, withVar, Html, Rx } from 'lib/rx'
import * as Options from 'view/options'

interface Params {
  options: Options.Model
  onSubmit: (options: Options.Model) => void
}

export function view({ options, onSubmit }: Params): Html {
  return withVar(options, (opts, updateOptions) =>
    h('form',
      { className: 'g-Form',
        onsubmit: opts.map(o =>
          (event: Event) => {
            event.preventDefault()
            onSubmit(o)
          }
        )
      },
      chordCheckbox({
        label: '', 
        checked: opts.map(o => o.major),
        onCheck: (checked => updateOptions(o => {
          o.major = checked
          return o
        }))
      }),
      chordCheckbox({ 
        label: '-', 
        checked: opts.map(o => o.minor),
        onCheck: (checked => updateOptions(o => {
          o.minor = checked
          return o
        }))
      }),
      chordCheckbox({ 
        label: '7', 
        checked: opts.map(o => o.seventh),
        onCheck: (checked => updateOptions(o => {
          o.seventh = checked
          return o
        }))
      }),
      chordCheckbox({ 
        label: '-7', 
        checked: opts.map(o => o.minorSeventh),
        onCheck: (checked => updateOptions(o => {
          o.minorSeventh = checked
          return o
        }))
      }),
      chordCheckbox({ 
        label: '7', 
        checked: opts.map(o => o.majorSeventh),
        onCheck: (checked => updateOptions(o => {
          o.majorSeventh = checked
          return o
        }))
      }),
      numberInput({ 
        label: 'BPM', 
        value: opts.map(o => o.bpm.toString()),
        onChange: (n => updateOptions(o => {
          o.bpm = n
          return o
        }))
      }),
      numberInput({ 
        label: 'Beats per Chord', 
        value: opts.map(o => o.beatsPerChord.toString()),
        onChange: (n => updateOptions(o => {
          o.beatsPerChord = n
          return o
        }))
      }),
      h('input', { type: 'submit', value: 'Play' })
    )
  )
}

interface ChordCheckboxParams {
  label: string
  checked: Rx<boolean>
  onCheck: (checked: boolean) => void
}

function chordCheckbox({ label, checked, onCheck }: ChordCheckboxParams): Html {
  return h('label',
    { className: 'g-ChordLabel' },
    h('input',
      { type: 'checkbox',
        checked,
        onchange: (event: Event) => onCheck((event.target as HTMLInputElement).checked)
      }
    ),
    label
  )
}

interface NumberInputParams {
  label: string
  value: Rx<string>
  onChange: (n: number) => void
}

function numberInput({ label, value, onChange }: NumberInputParams): Html {
  return h('label',
    h('input',
      { type: 'number',
        value,
        onchange: (event: Event) => {
          const n = parseInt((event.target as HTMLInputElement).value)
          if (typeof n === 'number') {
            onChange(n)
          }
        }
      }
    ),
    label
  )
}