forked from benpate/hyperscript-widgets
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmultiselect._hs
127 lines (103 loc) · 2.87 KB
/
multiselect._hs
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
behavior multiselect
init
add .multiselect
add [@role="menu"]
tell <label/> in me
add [@tabIndex=0]
add [@role="menuitem"]
end
tell <input/> in me
add [@role="menuitemcheckbox"]
end
-- if available, make the label sortable
if Sortable is not null then
tell <div.options/> in me
make a Sortable from yourself, {animation:150, whisperClass:'multiselect-whisper', onEnd: \ evt -> evt.item.focus()}
end
end
on change
set label to the closest <label/> to the target
if label is not null then
take .selected for label
end
on click from <button[data-sort=up]/> in me
set currentLabel to getSelectedLabel(me)
if currentLabel is null then
exit
end
set container to the currentLabel's parentNode
set previousLabel to the currentLabel's previousElementSibling
if previousLabel is null then
exit
end
container.insertBefore(currentLabel, previousLabel)
focus() the target
on click from <button[data-sort=down]/> in me
set currentLabel to getSelectedLabel(me)
if currentLabel is null then
exit
end
set container to the currentLabel's parentNode
set nextLabel to the currentLabel's nextElementSibling
log nextLabel
if nextLabel is null then
exit
end
container.insertBefore(nextLabel, currentLabel)
focus() the target
on focus from <label/> in me
take .selected for target
on focus from <input/> in me
focus() the closest <label/> to the target
on keydown[code=="ArrowUp"]
halt the event
set currentLabel to getSelectedLabel(me)
set previousLabel to previous <label/> from currentLabel
if previousLabel is not null then
take .selected for previousLabel
if currentLabel is document.activeElement then
focus() the previousLabel
end
end
on keydown[code=="ArrowDown"]
halt the event
set currentLabel to getSelectedLabel(me)
set nextLabel to next <label/> from currentLabel
if nextLabel is not null then
take .selected for nextLabel
if currentLabel is document.activeElement then
focus() the nextLabel
end
end
on keypress[code=="Space"]
-- handle "sort" buttons
if target[@data-sort] is not null then
exit
end
-- otherwise, toggle checkboxes
set selection to first <label.selected/> in me
if selection is not null then
set input to first <input/> in selection
set input.checked to (input.checked == false)
focus() the selection
halt the event
end
end
end
def getSelectedLabel(container)
-- try the .selected label
set result to the first <label.selected/> in container
if result is not null then
return result
end
-- try the document's active element
set result to document's activeElement
if (closest <div.multiselect/> to result) is me then
take .selected for result
return result
end
-- bail out to the first label in the container
set result to first <label/> in container
take .selected for result
return result
end