@lemonadejs/dropdown 3.0.3 → 3.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,333 +1,601 @@
1
- /**
2
- * Implementar o page up and down
3
- * botao reset e done
4
- * traducoes
5
- */
6
- if (!lemonade && typeof (require) === 'function') {
7
- var lemonade = require('lemonadejs');
8
- }
9
-
10
- if (!Modal && typeof (require) === 'function') {
11
- var Modal = require('@lemonadejs/modal');
12
- }
13
-
14
- if (!lazyloading && typeof (require) === 'function') {
15
- var lazyloading = require('@lemonadejs/lazy-loading');
16
- }
17
-
18
- ; (function (global, factory) {
19
- typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
20
- typeof define === 'function' && define.amd ? define(factory) :
21
- global.Dropdown = factory();
22
- }(this, (function () {
23
-
24
- const Dropdown = function () {
25
- let self = this;
26
-
27
- let group = null;
28
- let value = [];
29
- let cursor = null;
30
-
31
- if (! self.width) {
32
- self.width = 260;
33
- }
34
-
35
- const setCursor = function(index) {
36
- let item = self.modal.lazyLoading.data[index];
37
- if (typeof(item) !== 'undefined') {
38
- item.cursor = true;
39
- // Move to the item position: TODO!
40
- if (! item.el || ! item.el.parentNode) {
41
- self.modal.lazyLoading.goto(item);
42
- }
43
- }
44
- }
45
-
46
- const removeCursor = function(reset) {
47
- if (typeof(self.modal.lazyLoading.data[cursor]) !== 'undefined') {
48
- self.modal.lazyLoading.data[cursor].cursor = false;
49
- }
50
- if (reset) {
51
- // Cursor is null
52
- cursor = null;
53
- }
54
- }
55
-
56
- const moveCursor = function(direction, jump) {
57
- // Remove cursor
58
- removeCursor();
59
- // Last item
60
- let last = self.modal.lazyLoading.data.length - 1;
61
- if (jump) {
62
- if (direction < 0) {
63
- cursor = 0;
64
- } else {
65
- cursor = last;
66
- }
67
- } else {
68
- // Position
69
- if (cursor === null) {
70
- cursor = 0;
71
- } else {
72
- // Move previous
73
- cursor = cursor + direction;
74
- }
75
- // Reach the boundaries
76
- if (direction < 0) {
77
- // Back to the last one
78
- if (cursor < 0) {
79
- cursor = last;
80
- }
81
- } else {
82
- // Back to the first one
83
- if (cursor > last) {
84
- cursor = 0;
85
- }
86
- }
87
- }
88
- // Add cursor
89
- setCursor(cursor);
90
- }
91
-
92
- const updateLabel = function() {
93
- if (value && value.length) {
94
- self.input.textContent = value.filter(v => v.selected).map(i => i.text).join('; ');
95
- }
96
- }
97
-
98
- self.onclose = function() {
99
- // Identify the new state of the dropdown
100
- self.state = false;
101
- // Update label
102
- updateLabel();
103
- // Update value
104
- self.value = getValue();
105
- // Editable
106
- self.el.children[0].removeAttribute('contenteditable');
107
- }
108
-
109
- self.onopen = function() {
110
- // Value
111
- let v = value[value.length-1];
112
- // Move to the correct position
113
- if (v) {
114
- // Go to the last item in the array of values
115
- self.modal.lazyLoading.goto(v);
116
- // Mark the position of the cursor to the same element
117
- cursor = self.modal.lazyLoading.data.indexOf(v);
118
- } else {
119
- // Loading the data inside the lazy loading
120
- self.modal.lazyLoading.data = self.data;
121
- }
122
- // Reset search
123
- if (self.autocomplete) {
124
- // Clear input
125
- self.input.textContent = '';
126
- // Editable
127
- self.el.children[0].setAttribute('contenteditable', true);
128
- // Focus on the item
129
- self.el.children[0].focus();
130
- }
131
-
132
- self.state = true;
133
- }
134
-
135
- const setValue = function(v) {
136
- // Values
137
- let newValue;
138
- if (! v) {
139
- newValue = [];
140
- } else if (! Array.isArray(v)) {
141
- if (typeof(v) === 'string') {
142
- newValue = v.split(';');
143
- } else {
144
- newValue = [v];
145
- }
146
- } else {
147
- newValue = v;
148
- }
149
-
150
- // Width && values
151
- value = [];
152
-
153
- self.data.map(function(s) {
154
- // Select values
155
- if (newValue.indexOf(s.value) !== -1) {
156
- s.selected = true;
157
- value.push(s);
158
- } else {
159
- s.selected = false;
160
- }
161
- });
162
-
163
- // Update label
164
- updateLabel();
165
- }
166
-
167
- const getValue = function() {
168
- if (value && value.length) {
169
- return value.filter(v => v.selected).map(i => i.value);
170
- }
171
- return [];
172
- }
173
-
174
- self.onload = function () {
175
- // Set the initial value
176
- if (self.value) {
177
- setValue(self.value);
178
- }
179
- // Re-order to make sure groups are in sequence
180
- self.data = self.data.sort((a, b) => {
181
- // Compare groups
182
- if (a.group && b.group) {
183
- return a.group.localeCompare(b.group);
184
- }
185
- return 0;
186
- });
187
- // Update the data of the lazy loading component
188
- self.modal.lazyLoading.data = self.data;
189
- // Estimate width
190
- let width = self.width;
191
- // Width && values
192
- self.data.map(function (s) {
193
- // Estimated width of the element
194
- width = Math.max(width, s.text.length * 8);
195
- });
196
- // Adjust the width
197
- let w = self.el.children[0].offsetWidth;
198
- if (width < w) {
199
- width = w;
200
- }
201
- // Estimated with based on the text
202
- if (self.width < width) {
203
- self.width = width;
204
- }
205
- self.el.style.width = self.width + 'px';
206
-
207
- // Focus out of the component
208
- self.el.addEventListener('focusout', function(e) {
209
- if (! (e.relatedTarget && self.el.contains(e.relatedTarget)) && ! self.el.contains(e.relatedTarget)) {
210
- if (! self.modal.closed) {
211
- self.close();
212
- }
213
- }
214
- })
215
-
216
- self.el.addEventListener('keydown', function(e) {
217
- if (e.key === 'ArrowUp') {
218
- moveCursor(-1);
219
- } else if (e.key === 'ArrowDown') {
220
- moveCursor(1);
221
- } else if (e.key === 'Home') {
222
- moveCursor(-1, true);
223
- } else if (e.key === 'End') {
224
- moveCursor(1, true);
225
- } else if (e.key === 'Enter') {
226
- // Select
227
- if (typeof(self.modal.lazyLoading.data[cursor]) !== 'undefined') {
228
- self.select(e, self.modal.lazyLoading.data[cursor]);
229
- e.preventDefault();
230
- e.stopImmediatePropagation();
231
- }
232
- } else {
233
- if (self.state && self.autocomplete) {
234
- // Filter options
235
- let data;
236
- if (! self.input.textContent) {
237
- data = self.data;
238
- } else {
239
- data = self.data.filter(item => {
240
- return item.text.toLowerCase().includes(self.input.textContent.toLowerCase()) ||
241
- (item.group && item.group.toLowerCase().includes(self.input.textContent.toLowerCase()));
242
- });
243
- }
244
- // Cursor
245
- removeCursor(true);
246
- // Update the data from the dropdown
247
- self.modal.lazyLoading.data = data;
248
- }
249
- }
250
- })
251
-
252
- if (document.documentElement.clientWidth < 800) {
253
- self.animation = true;
254
- }
255
- }
256
-
257
- self.onchange = function (prop) {
258
- if (prop === 'value') {
259
- setValue(self.value);
260
- }
261
- }
262
-
263
- self.open = function () {
264
- if (self.modal.closed) {
265
- self.modal.closed = false;
266
- }
267
- }
268
-
269
- self.close = function () {
270
- // Close the modal
271
- self.modal.closed = true;
272
- // Remove cursor
273
- removeCursor(true);
274
- }
275
-
276
- self.toggle = function() {
277
- if (self.modal.closed) {
278
- self.open();
279
- } else {
280
- self.close();
281
- }
282
- }
283
-
284
- self.select = function(e, s) {
285
- if (self.multiple === true) {
286
- let position = value.indexOf(s);
287
- if (position === -1) {
288
- value.push(s);
289
- s.selected = true;
290
- } else {
291
- value.splice(position, 1);
292
- s.selected = false;
293
- }
294
- } else {
295
- if (value[0]) {
296
- value[0].selected = false;
297
- }
298
- s.selected = true;
299
- value = [s];
300
- // Close the modal
301
- self.close();
302
- }
303
- }
304
-
305
- self.getGroup = function(g) {
306
- let groupName = g && g === group ? '' : g;
307
- group = g;
308
- return groupName;
309
- }
310
-
311
- return `<div class="lm-dropdown" data-type="{{self.type}}" data-state="{{self.state}}">
312
- <div class="lm-dropdown-input" onkeydown="self.toggle" onfocus="self.open" placeholder="{{self.placeholder}}" :ref="self.input" tabindex="0"></div>
313
- <Modal :ref="self.modal" :closed="true" :onclose="self.onclose" :onopen="self.onopen" :width="self.width" :animation="self.animation">
314
- <Lazyloading :data="self.data" :ref="self.lazyLoading" :height="330">
315
- <div class="lm-dropdown-item" onclick="self.parent.parent.parent.select" data-cursor="{{self.cursor}}" data-selected="{{self.selected}}" data-group="{{self.parent.parent.parent.getGroup(self.group)}}">
316
- <div><img :src="self.image" /><span>{{self.text}}</span></div>
317
- </div>
318
- </Lazyloading>
319
- </Modal>
320
- </div>`;
321
- }
322
-
323
- lemonade.setComponents({ Dropdown: Dropdown });
324
-
325
- return function (root, options) {
326
- if (typeof (root) === 'object') {
327
- lemonade.render(Dropdown, root, options)
328
- return options;
329
- } else {
330
- return Dropdown.call(this, root)
331
- }
332
- }
1
+ /**
2
+ * Implementar o page up and down
3
+ * botao reset e done
4
+ * traducoes
5
+ */
6
+ if (!lemonade && typeof (require) === 'function') {
7
+ var lemonade = require('lemonadejs');
8
+ }
9
+
10
+ if (!Modal && typeof (require) === 'function') {
11
+ var Modal = require('@lemonadejs/modal');
12
+ }
13
+
14
+ ; (function (global, factory) {
15
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
16
+ typeof define === 'function' && define.amd ? define(factory) :
17
+ global.Dropdown = factory();
18
+ }(this, (function () {
19
+
20
+ // Default row height
21
+ let defaultRowHeight = 26;
22
+
23
+ const lazyLoading = function(self) {
24
+ /**
25
+ * Compare two arrays to see if contains exact the same elements
26
+ * @param {number[]} a1
27
+ * @param {number[]} a2
28
+ */
29
+ const compareArray = function (a1, a2) {
30
+ if (! a1 || ! a2) {
31
+ return false;
32
+ }
33
+
34
+ let i = a1.length;
35
+ if (i !== a2.length) {
36
+ return false;
37
+ }
38
+ while (i--) {
39
+ if (a1[i] !== a2[i]) {
40
+ return false;
41
+ }
42
+ }
43
+ return true;
44
+ }
45
+
46
+ /**
47
+ * Get the position from top of a row by its index
48
+ * @param item
49
+ * @returns {number}
50
+ */
51
+ const getRowPosition = function(item) {
52
+ // Position from top
53
+ let top = 0;
54
+ if (item) {
55
+ let items = self.rows;
56
+ if (items && items.length) {
57
+ let index = self.rows.indexOf(item);
58
+ // Go through the items
59
+ for (let j = 0; j < index; j++) {
60
+ top += items[j].height || defaultRowHeight;
61
+ }
62
+ }
63
+ }
64
+ return top;
65
+ }
66
+
67
+ const updateScroll = function() {
68
+ let items = self.rows;
69
+ if (items) {
70
+ // Total of items in the container
71
+ let numOfItems = items.length;
72
+ // Position from top
73
+ let height = 0;
74
+ // Go through the items
75
+ for (let j = 0; j < numOfItems; j++) {
76
+ height += items[j].height || defaultRowHeight;
77
+ }
78
+ // Update height
79
+ scroll.style.height = height + 'px';
80
+ }
81
+ }
82
+
83
+ const getVisibleRows = function(reset) {
84
+ let items = self.rows;
85
+ if (items) {
86
+ let rows = [];
87
+ // Total of items in the container
88
+ let numOfItems = items.length;
89
+ // Height
90
+ let height = 0;
91
+ // Controls
92
+ let y = el.scrollTop;
93
+ let h = y + (el.offsetHeight || self.height);
94
+ // Go through the items
95
+ for (let j = 0; j < numOfItems; j++) {
96
+ if (items[j].visible !== false) {
97
+ // Height
98
+ let rowHeight = items[j].height || defaultRowHeight;
99
+ // Return on partial width
100
+ if (height + rowHeight > y && height < h) {
101
+ rows.push(items[j]);
102
+ }
103
+ height += rowHeight;
104
+ }
105
+ }
106
+
107
+ // Update visible rows
108
+ if (reset || ! compareArray(rows, self.result)) {
109
+ self.result = rows;
110
+ // Adjust scroll height
111
+ let adjustScroll = reset;
112
+ // Adjust scrolling
113
+ for (let i = 0; i < rows.length; i++) {
114
+ // Item
115
+ let item = rows[i];
116
+ // Item height
117
+ let h = item.el.offsetHeight;
118
+ // Update row height
119
+ if (! item.height || h !== item.height) {
120
+ // Keep item height
121
+ item.height = h;
122
+ // Adjust total height
123
+ adjustScroll = true;
124
+ }
125
+ }
126
+
127
+ // Update scroll if the height of one element has been changed
128
+ if (adjustScroll) {
129
+ updateScroll();
130
+ }
131
+ }
132
+
133
+ // Adjust position of the first element
134
+ let position = getRowPosition(self.result[0]);
135
+ let diff = position - el.scrollTop;
136
+ if (diff > 0) {
137
+ diff = 0;
138
+ }
139
+ self.container.style.top = diff + 'px';
140
+ }
141
+ }
142
+
143
+ /**
144
+ * Move the position to the top and re-render based on the scroll
145
+ * @param reset
146
+ */
147
+ const render = function (reset) {
148
+ // Move scroll to the top
149
+ el.scrollTop = 0;
150
+ // Append first batch
151
+ getVisibleRows(reset);
152
+ }
153
+
154
+ self.adjustPosition = function(item) {
155
+ if (item.el) {
156
+ let calc = item.el.offsetTop + item.el.offsetHeight;
157
+ if (calc > el.offsetHeight) {
158
+ let size = calc - el.offsetHeight;
159
+ if (size < defaultRowHeight) {
160
+ size = defaultRowHeight;
161
+ }
162
+ el.scrollTop -= -1 * size;
163
+ }
164
+ }
165
+ }
166
+
167
+ // Controls
168
+ const scrollControls = function() {
169
+ // Get all items that should be visible based on the position of the scroll
170
+ getVisibleRows(false);
171
+ }
172
+
173
+ // Element for scrolling
174
+ let el = self.container.parentNode;
175
+ el.classList.add('lm-lazy');
176
+ // Div to represent the height of the content
177
+ const scroll = document.createElement('div');
178
+ scroll.classList.add('lm-lazy-scroll');
179
+ // Force the height and add scrolling
180
+ el.appendChild(scroll);
181
+ el.addEventListener('scroll', scrollControls);
182
+ el.addEventListener('wheel', scrollControls);
183
+ self.container.classList.add('lm-lazy-items');
184
+
185
+ self.goto = function(item) {
186
+ el.scrollTop = getRowPosition(item);
187
+ // Get all items that should be visible based on the position of the scroll
188
+ getVisibleRows(false);
189
+ }
190
+
191
+ return (prop) => {
192
+ if (prop === 'rows') {
193
+ render(true);
194
+ }
195
+ }
196
+ }
197
+
198
+ const Dropdown = function () {
199
+ let self = this;
200
+ let value = [];
201
+ let cursor = null;
202
+
203
+ if (! self.width) {
204
+ self.width = 260;
205
+ }
206
+
207
+ // Lazy loading global instance
208
+ let lazyloading = null;
209
+
210
+ const setData = function() {
211
+ // Re-order to make sure groups are in sequence
212
+ self.data.sort((a, b) => {
213
+ // Compare groups
214
+ if (a.group && b.group) {
215
+ return a.group.localeCompare(b.group);
216
+ }
217
+ return 0;
218
+ });
219
+ let group = '';
220
+ // Define group headers
221
+ self.data.map((v) => {
222
+ // Compare groups
223
+ if (v.group && v.group !== group) {
224
+ v.header = true;
225
+ group = v.group;
226
+ }
227
+ });
228
+ // Estimate width
229
+ let width = self.width;
230
+ // Width && values
231
+ self.data.map(function (s) {
232
+ // Estimated width of the element
233
+ width = Math.max(width, s.text.length * 8);
234
+ });
235
+ // Adjust the width
236
+ let w = self.input.offsetWidth;
237
+ if (width < w) {
238
+ width = w;
239
+ }
240
+ // Estimated with based on the text
241
+ if (self.width < width) {
242
+ self.width = width;
243
+ }
244
+ self.el.style.width = self.width + 'px';
245
+ // Height
246
+ self.height = 400;
247
+ // Animation for mobile
248
+ if (document.documentElement.clientWidth < 800) {
249
+ self.animation = true;
250
+ }
251
+ // Data to be listed
252
+ self.rows = self.data;
253
+ // Set the initial value
254
+ if (typeof(self.value) !== 'undefined') {
255
+ setValue(self.value);
256
+ }
257
+ }
258
+
259
+ const setCursor = function(index) {
260
+ let item = self.rows[index];
261
+ if (typeof(item) !== 'undefined') {
262
+ // Set cursor number
263
+ cursor = index;
264
+ // Set visual indication
265
+ item.cursor = true;
266
+ // Go to the item on the scroll in case the item is not on the viewport
267
+ if (! item.el || ! item.el.parentNode) {
268
+ // Goto method
269
+ self.goto(item);
270
+ }
271
+ // Adjust cursor position
272
+ setTimeout(function() {
273
+ self.adjustPosition(item);
274
+ });
275
+ }
276
+ }
277
+
278
+ const removeCursor = function(reset) {
279
+ if (cursor !== null) {
280
+ if (typeof(self.rows[cursor]) !== 'undefined') {
281
+ self.rows[cursor].cursor = false;
282
+ }
283
+ if (reset) {
284
+ // Cursor is null
285
+ cursor = null;
286
+ }
287
+ }
288
+ }
289
+
290
+ const moveCursor = function(direction, jump) {
291
+ // Remove cursor
292
+ removeCursor();
293
+ // Last item
294
+ let last = self.rows.length - 1;
295
+ if (jump) {
296
+ if (direction < 0) {
297
+ cursor = 0;
298
+ } else {
299
+ cursor = last;
300
+ }
301
+ } else {
302
+ // Position
303
+ if (cursor === null) {
304
+ cursor = 0;
305
+ } else {
306
+ // Move previous
307
+ cursor = cursor + direction;
308
+ }
309
+ // Reach the boundaries
310
+ if (direction < 0) {
311
+ // Back to the last one
312
+ if (cursor < 0) {
313
+ cursor = last;
314
+ }
315
+ } else {
316
+ // Back to the first one
317
+ if (cursor > last) {
318
+ cursor = 0;
319
+ }
320
+ }
321
+ }
322
+ // Add cursor
323
+ setCursor(cursor);
324
+ }
325
+
326
+ const updateLabel = function() {
327
+ if (value && value.length) {
328
+ self.input.textContent = value.filter(v => v.selected).map(i => i.text).join('; ');
329
+ }
330
+ }
331
+
332
+ const setValue = function(v) {
333
+ // Values
334
+ let newValue;
335
+ if (! Array.isArray(v)) {
336
+ if (typeof(v) === 'string') {
337
+ newValue = v.split(';');
338
+ } else {
339
+ newValue = [v];
340
+ }
341
+ } else {
342
+ newValue = v;
343
+ }
344
+
345
+ // Width && values
346
+ value = [];
347
+
348
+ self.data.map(function(s) {
349
+ // Select values
350
+ if (newValue.indexOf(s.value) !== -1) {
351
+ s.selected = true;
352
+ value.push(s);
353
+ } else {
354
+ s.selected = false;
355
+ }
356
+ });
357
+
358
+ // Update label
359
+ updateLabel();
360
+ }
361
+
362
+ const getValue = function() {
363
+ if (value && value.length) {
364
+ return value.filter(v => v.selected).map(i => i.value);
365
+ }
366
+ return [];
367
+ }
368
+
369
+ const onclose = function() {
370
+ // Cursor
371
+ removeCursor();
372
+ // Reset search
373
+ if (self.autocomplete && self.input.textContent) {
374
+ // Go to begin of the data
375
+ self.rows = self.data;
376
+ // Remove editable attribute
377
+ self.input.removeAttribute('contenteditable');
378
+ // Clear input
379
+ self.input.textContent = '';
380
+ }
381
+ // Update label
382
+ updateLabel();
383
+ // Update value
384
+ self.value = getValue();
385
+ // Identify the new state of the dropdown
386
+ self.state = false;
387
+ }
388
+
389
+ const onopen = function() {
390
+ self.state = true;
391
+ // Value
392
+ let v = value[value.length-1];
393
+ // Cursor
394
+ removeCursor();
395
+ // Move to the correct position
396
+ if (v) {
397
+ // Go to the last item in the array of values
398
+ self.goto(v);
399
+ // Mark the position of the cursor to the same element
400
+ setCursor(self.rows.indexOf(v));
401
+ } else {
402
+ // Go to begin of the data
403
+ self.rows = self.data;
404
+ }
405
+ // Prepare search field
406
+ if (self.autocomplete) {
407
+ // Clear input
408
+ self.input.textContent = '';
409
+ // Editable
410
+ self.input.setAttribute('contenteditable', true);
411
+ // Focus on the item
412
+ self.input.focus();
413
+ }
414
+ }
415
+
416
+ self.search = function() {
417
+ if (self.state && self.autocomplete) {
418
+ // Filter options
419
+ let data;
420
+ if (! self.input.textContent) {
421
+ data = self.data;
422
+ } else {
423
+ data = self.data.filter(item => {
424
+ return item.selected === true ||
425
+ (item.text.toLowerCase().includes(self.input.textContent.toLowerCase())) ||
426
+ (item.group && item.group.toLowerCase().includes(self.input.textContent.toLowerCase()));
427
+ });
428
+ }
429
+ // Cursor
430
+ removeCursor(true);
431
+ // Update the data from the dropdown
432
+ self.rows = data;
433
+ }
434
+ }
435
+
436
+ self.open = function () {
437
+ if (self.modal && self.modal.closed) {
438
+ self.modal.closed = false;
439
+ }
440
+ }
441
+
442
+ self.close = function () {
443
+ // Close the modal
444
+ if (self.modal) {
445
+ self.modal.closed = true;
446
+ // Remove cursor
447
+ removeCursor(true);
448
+ }
449
+ }
450
+
451
+ self.toggle = function() {
452
+ if (self.modal) {
453
+ if (self.modal.closed) {
454
+ self.open();
455
+ } else {
456
+ self.close();
457
+ }
458
+ }
459
+ }
460
+
461
+ self.select = function(e, s) {
462
+ if (s) {
463
+ if (self.multiple === true) {
464
+ let position = value.indexOf(s);
465
+ if (position === -1) {
466
+ value.push(s);
467
+ s.selected = true;
468
+ } else {
469
+ value.splice(position, 1);
470
+ s.selected = false;
471
+ }
472
+ } else {
473
+ if (value[0] === s) {
474
+ s.selected = !s.selected;
475
+ } else {
476
+ if (value[0]) {
477
+ value[0].selected = false;
478
+ }
479
+ s.selected = true;
480
+ }
481
+ if (s.selected) {
482
+ value = [s];
483
+ } else {
484
+ value = [];
485
+ }
486
+ // Close the modal
487
+ self.close();
488
+ }
489
+ }
490
+ }
491
+
492
+ self.getGroup = function() {
493
+ if (this.group && this.header) {
494
+ return this.group;
495
+ } else {
496
+ return '';
497
+ }
498
+ }
499
+
500
+ self.onload = function () {
501
+ if (self.type !== "inline") {
502
+ // Create modal instance
503
+ self.modal = {
504
+ closed: true,
505
+ focus: false,
506
+ width: self.width,
507
+ 'auto-close': false,
508
+ onopen: onopen,
509
+ onclose: onclose,
510
+ };
511
+ // Generate modal
512
+ Modal(self.el.children[1], self.modal);
513
+ } else {
514
+ // For inline dropdown
515
+ self.el.setAttribute('tabindex', 0);
516
+ // Remove search
517
+ self.input.remove();
518
+ }
519
+ // Loading controls
520
+ lazyloading = lazyLoading(self);
521
+ // Process the data
522
+ setData();
523
+ // Focus out of the component
524
+ self.el.addEventListener('focusout', function(e) {
525
+ if (self.modal) {
526
+ if (! (e.relatedTarget && self.el.contains(e.relatedTarget)) && !self.el.contains(e.relatedTarget)) {
527
+ if (! self.modal.closed) {
528
+ self.close();
529
+ }
530
+ }
531
+ }
532
+ })
533
+ // Key events
534
+ self.el.addEventListener('keydown', function(e) {
535
+ let prevent = false;
536
+ if (e.key === 'ArrowUp') {
537
+ moveCursor(-1);
538
+ prevent = true;
539
+ } else if (e.key === 'ArrowDown') {
540
+ moveCursor(1);
541
+ prevent = true;
542
+ } else if (e.key === 'Home') {
543
+ moveCursor(-1, true);
544
+ } else if (e.key === 'End') {
545
+ moveCursor(1, true);
546
+ } else if (e.key === 'Enter') {
547
+ self.select(e, self.rows[cursor]);
548
+ prevent = true;
549
+ } else {
550
+ if (e.keyCode === 32 && ! self.autocomplete) {
551
+ self.select(e, self.rows[cursor]);
552
+ }
553
+ }
554
+
555
+ if (prevent) {
556
+ e.preventDefault();
557
+ e.stopImmediatePropagation();
558
+ }
559
+ });
560
+ }
561
+
562
+ self.onchange = function(prop) {
563
+ if (prop === 'value') {
564
+ setValue(self.value);
565
+ } else if (prop === 'data') {
566
+ setData();
567
+ }
568
+
569
+ if (typeof(lazyloading) === 'function') {
570
+ lazyloading(prop);
571
+ }
572
+ }
573
+
574
+ return `<div class="lm-dropdown" data-type="{{self.type}}" data-state="{{self.state}}">
575
+ <div class="lm-dropdown-header">
576
+ <div class="lm-dropdown-input" oninput="self.search" onfocus="self.open" placeholder="{{self.placeholder}}" :ref="self.input" tabindex="0"></div>
577
+ <button onclick="self.close" class="lm-dropdown-done">Done</button>
578
+ </div>
579
+ <div class="lm-dropdown-content">
580
+ <div>
581
+ <div :loop="self.result" :ref="self.container" :rows="self.rows">
582
+ <div class="lm-dropdown-item" onclick="self.parent.select" data-cursor="{{self.cursor}}" data-selected="{{self.selected}}" data-group="{{self.parent.getGroup}}">
583
+ <div><img :src="self.image" /><span>{{self.text}}</span></div>
584
+ </div>
585
+ </div>
586
+ </div>
587
+ </div>
588
+ </div>`;
589
+ }
590
+
591
+ lemonade.setComponents({ Dropdown: Dropdown });
592
+
593
+ return function (root, options) {
594
+ if (typeof (root) === 'object') {
595
+ lemonade.render(Dropdown, root, options)
596
+ return options;
597
+ } else {
598
+ return Dropdown.call(this, root)
599
+ }
600
+ }
333
601
  })));