@lemonadejs/dropdown 3.0.4 → 3.0.9

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