forked from slab/quill
-
Notifications
You must be signed in to change notification settings - Fork 0
/
picker.js
121 lines (110 loc) · 3.56 KB
/
picker.js
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 DropdownIcon from '../assets/icons/dropdown.svg';
class Picker {
constructor(select) {
this.select = select;
this.container = document.createElement('span');
this.buildPicker();
this.select.style.display = 'none';
this.select.parentNode.insertBefore(this.container, this.select);
['mousedown', 'touchstart'].forEach((name) => {
this.label.addEventListener(name, (event) => {
this.container.classList.toggle('ql-expanded');
event.preventDefault(); // prevent focus loss
});
});
this.select.addEventListener('change', this.update.bind(this));
}
buildItem(option) {
let item = document.createElement('span');
item.classList.add('ql-picker-item');
if (option.hasAttribute('value')) {
item.dataset.value = option.getAttribute('value');
}
if (option.textContent) {
item.dataset.label = option.textContent;
}
['mousedown', 'touchstart'].forEach((name) => {
item.addEventListener(name, (event) => {
this.selectItem(item, true);
event.preventDefault();
});
});
return item;
}
buildLabel() {
let label = document.createElement('span');
label.classList.add('ql-picker-label');
label.innerHTML = DropdownIcon;
this.container.appendChild(label);
return label;
}
buildOptions() {
let options = document.createElement('span');
options.classList.add('ql-picker-options');
[].slice.call(this.select.options).forEach((option) => {
let item = this.buildItem(option);
options.appendChild(item);
if (option.hasAttribute('selected')) {
this.selectItem(item);
}
});
this.container.appendChild(options);
}
buildPicker() {
[].slice.call(this.select.attributes).forEach((item) => {
this.container.setAttribute(item.name, item.value);
});
this.container.classList.add('ql-picker');
this.label = this.buildLabel();
this.buildOptions();
}
close() {
this.container.classList.remove('ql-expanded');
}
selectItem(item, trigger = false) {
let selected = this.container.querySelector('.ql-selected');
if (selected != null) {
selected.classList.remove('ql-selected');
}
if (item != null) {
item.classList.add('ql-selected');
this.select.selectedIndex = [].indexOf.call(item.parentNode.children, item);
if (item.dataset.value) {
this.label.dataset.value = item.dataset.value;
} else {
delete this.label.dataset.value;
}
if (item.dataset.label) {
this.label.dataset.label = item.dataset.label;
} else {
delete this.label.dataset.label;
}
if (trigger) {
if (typeof Event === 'function') {
this.select.dispatchEvent(new Event('change'));
} else if (typeof Event === 'object') { // IE11
let event = document.createEvent('Event');
event.initEvent('change', true, true);
this.select.dispatchEvent(event);
}
}
} else {
delete this.label.dataset.value;
delete this.label.dataset.label;
}
this.close();
}
update() {
let option;
if (this.select.selectedIndex > -1) {
let item = this.container.querySelector('.ql-picker-options').children[this.select.selectedIndex]
option = this.select.options[this.select.selectedIndex];
this.selectItem(item);
} else {
this.selectItem(null);
}
let isActive = option != null && option !== this.select.querySelector('option[selected]');
this.label.classList.toggle('ql-active', isActive);
}
}
export default Picker;