forked from myitcv/react
/
select.go
139 lines (104 loc) · 2.3 KB
/
select.go
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package imm
import (
"fmt"
"strconv"
"honnef.co/go/js/dom"
r "github.com/lijianying10/react"
)
const (
noEntry = "-1"
)
//go:generate reactGen
//go:generate immutableGen
type Label interface {
Label() string
}
type _Imm_LabelEntries []Label
type _Imm_strEntrySelect map[string]Label
type ImmSelectEntry interface {
Range() []Label
}
// SelectDef is a wrapper around the github.com/lijianying10/react.SelectDef component. It allows
// any value implementing the Label interface to be selected
//
type SelectDef struct {
r.ComponentDef
}
type OnSelect interface {
OnSelect(i Label)
}
type SelectProps struct {
Entry Label
Entries ImmSelectEntry
OnSelect
}
type SelectState struct {
currEntry string
entries *entriesKeysSelect
entriesMap *strEntrySelect
}
type entryKey struct {
key string
p Label
}
type _Imm_entriesKeysSelect []entryKey
// Select creates a new instance of the SelectDef component with the provided props
//
func Select(props SelectProps) *SelectElem {
return buildSelectElem(props)
}
func (p SelectDef) ComponentWillMount() {
p.updateMap(p.Props().Entries)
}
func (p SelectDef) ComponentWillReceiveProps(props SelectProps) {
p.updateMap(props.Entries)
}
func (p SelectDef) updateMap(es ImmSelectEntry) {
eks := newEntriesKeysSelect().AsMutable()
defer eks.AsImmutable(nil)
kem := newStrEntrySelect().AsMutable()
defer kem.AsImmutable(nil)
for i, p := range es.Range() {
k := strconv.Itoa(i)
kem.Set(k, p)
eks.Append(entryKey{
key: k,
p: p,
})
}
kem.Set(noEntry, nil)
st := p.State()
st.entries = eks
st.entriesMap = kem
p.SetState(st)
}
func (p SelectDef) Render() r.Element {
var ps []*r.OptionElem
for _, v := range p.State().entries.Range() {
p := r.Option(
&r.OptionProps{Value: v.key},
r.S(v.p.Label()),
)
ps = append(ps, p)
}
return r.Select(
&r.SelectProps{
Value: p.State().currEntry,
OnChange: changeEntry{p},
},
ps...,
)
}
type changeEntry struct{ SelectDef }
func (c changeEntry) OnChange(e *r.SyntheticEvent) {
v := e.Target().(*dom.HTMLSelectElement).Value
p := c.SelectDef
s := c.SelectDef.State()
l, ok := p.State().entriesMap.Get(v)
if !ok {
panic(fmt.Errorf("Select component selected value %q that we don't know about", v))
}
s.currEntry = v
p.SetState(s)
p.Props().OnSelect.OnSelect(l)
}