@lemonadejs/dropdown 3.2.2 → 3.6.0
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.d.ts +2 -0
- package/dist/index.js +149 -70
- package/dist/react.d.ts +4 -1
- package/dist/style.css +12 -6
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -45,6 +45,8 @@ declare namespace Dropdown {
|
|
|
45
45
|
insert?: boolean;
|
|
46
46
|
/** Specifies the URL for fetching the data. */
|
|
47
47
|
url?: string;
|
|
48
|
+
/** Allow empty. Default: true */
|
|
49
|
+
allowempty?: boolean;
|
|
48
50
|
/** Event handler for value changes */
|
|
49
51
|
onchange?: (obj: object, newValue: string|number) => void;
|
|
50
52
|
/** Event handler for when the dropdown is ready */
|
package/dist/index.js
CHANGED
|
@@ -242,20 +242,96 @@ if (!Modal && typeof (require) === 'function') {
|
|
|
242
242
|
}
|
|
243
243
|
}
|
|
244
244
|
|
|
245
|
-
const
|
|
245
|
+
const getAttributeName = function(prop) {
|
|
246
|
+
if (prop.substring(0,1) === ':') {
|
|
247
|
+
prop = prop.substring(1);
|
|
248
|
+
} else if (prop.substring(0,3) === 'lm-') {
|
|
249
|
+
prop = prop.substring(3);
|
|
250
|
+
}
|
|
251
|
+
return prop.toLowerCase();
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
const extractFromHtml = function(element) {
|
|
255
|
+
let data = [];
|
|
256
|
+
// Content
|
|
257
|
+
for (let i = 0; i < element.children.length; i++) {
|
|
258
|
+
let e = element.children[i];
|
|
259
|
+
let item = {
|
|
260
|
+
text: e.textContent || e.getAttribute('title'),
|
|
261
|
+
value: e.getAttribute('value'),
|
|
262
|
+
}
|
|
263
|
+
if (item.value == null) {
|
|
264
|
+
item.value = item.text;
|
|
265
|
+
}
|
|
266
|
+
data.push(item);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
return data;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
const extract = function(children) {
|
|
273
|
+
let data = [];
|
|
274
|
+
|
|
275
|
+
if (this.tagName) {
|
|
276
|
+
data = extractFromHtml(this);
|
|
277
|
+
// Remove all elements
|
|
278
|
+
this.textContent = '';
|
|
279
|
+
} else {
|
|
280
|
+
// Get data
|
|
281
|
+
if (typeof(children) === 'string') {
|
|
282
|
+
// Version 4
|
|
283
|
+
let d = document.createElement('div');
|
|
284
|
+
d.innerHTML = children;
|
|
285
|
+
data = extractFromHtml(d);
|
|
286
|
+
} else if (children && children.length) {
|
|
287
|
+
// Version 5
|
|
288
|
+
children.forEach((v) => {
|
|
289
|
+
let item = {}
|
|
290
|
+
v.props.forEach((prop) => {
|
|
291
|
+
item[getAttributeName(prop.name)] = prop.value;
|
|
292
|
+
});
|
|
293
|
+
if (! item.text) {
|
|
294
|
+
item.text = v.children[0]?.props[0]?.value || '';
|
|
295
|
+
}
|
|
296
|
+
data.push(item);
|
|
297
|
+
});
|
|
298
|
+
// Block children
|
|
299
|
+
children.length = 0;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
return data;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
const Dropdown = function (children) {
|
|
246
307
|
let self = this;
|
|
308
|
+
// Data
|
|
309
|
+
let data = [];
|
|
247
310
|
// Internal value controllers
|
|
248
311
|
let value = [];
|
|
249
312
|
// Cursor
|
|
250
313
|
let cursor = null;
|
|
251
314
|
// Control events
|
|
252
315
|
let ignoreEvents = false;
|
|
253
|
-
// Default
|
|
254
|
-
if (!self.width) {
|
|
316
|
+
// Default width
|
|
317
|
+
if (! self.width) {
|
|
255
318
|
self.width = 260;
|
|
256
319
|
}
|
|
257
320
|
// Lazy loading global instance
|
|
258
321
|
let lazyloading = null;
|
|
322
|
+
|
|
323
|
+
// Data
|
|
324
|
+
if (! Array.isArray(self.data)) {
|
|
325
|
+
self.data = [];
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
let d = extract.call(this, children);
|
|
329
|
+
if (d) {
|
|
330
|
+
d.forEach((v) => {
|
|
331
|
+
self.data.push(v)
|
|
332
|
+
})
|
|
333
|
+
}
|
|
334
|
+
|
|
259
335
|
// Custom events defined by the user
|
|
260
336
|
let onload = self.onload;
|
|
261
337
|
let onchange = self.onchange;
|
|
@@ -332,9 +408,11 @@ if (!Modal && typeof (require) === 'function') {
|
|
|
332
408
|
const setData = function () {
|
|
333
409
|
// Estimate width
|
|
334
410
|
let width = self.width;
|
|
411
|
+
// Data
|
|
412
|
+
data = JSON.parse(JSON.stringify(self.data));
|
|
335
413
|
// Re-order to make sure groups are in sequence
|
|
336
|
-
if (
|
|
337
|
-
|
|
414
|
+
if (data && data.length) {
|
|
415
|
+
data.sort((a, b) => {
|
|
338
416
|
// Compare groups
|
|
339
417
|
if (a.group && b.group) {
|
|
340
418
|
return a.group.localeCompare(b.group);
|
|
@@ -343,15 +421,15 @@ if (!Modal && typeof (require) === 'function') {
|
|
|
343
421
|
});
|
|
344
422
|
let group = '';
|
|
345
423
|
// Define group headers
|
|
346
|
-
|
|
424
|
+
data.map((v) => {
|
|
347
425
|
// Compare groups
|
|
348
426
|
if (v && v.group && v.group !== group) {
|
|
349
|
-
v.header =
|
|
427
|
+
v.header = v.group;
|
|
350
428
|
group = v.group;
|
|
351
429
|
}
|
|
352
430
|
});
|
|
353
431
|
// Width && values
|
|
354
|
-
|
|
432
|
+
data.map(function (s) {
|
|
355
433
|
// Estimated width of the element
|
|
356
434
|
if (s.text) {
|
|
357
435
|
width = Math.max(width, s.text.length * 8);
|
|
@@ -375,7 +453,7 @@ if (!Modal && typeof (require) === 'function') {
|
|
|
375
453
|
self.animation = true;
|
|
376
454
|
}
|
|
377
455
|
// Data to be listed
|
|
378
|
-
self.rows =
|
|
456
|
+
self.rows = data;
|
|
379
457
|
}
|
|
380
458
|
|
|
381
459
|
const updateLabel = function () {
|
|
@@ -386,7 +464,7 @@ if (!Modal && typeof (require) === 'function') {
|
|
|
386
464
|
}
|
|
387
465
|
}
|
|
388
466
|
|
|
389
|
-
const setValue = function (v) {
|
|
467
|
+
const setValue = function (v, ignoreEvent) {
|
|
390
468
|
// Values
|
|
391
469
|
let newValue;
|
|
392
470
|
if (!Array.isArray(v)) {
|
|
@@ -402,8 +480,8 @@ if (!Modal && typeof (require) === 'function') {
|
|
|
402
480
|
// Width && values
|
|
403
481
|
value = [];
|
|
404
482
|
|
|
405
|
-
if (Array.isArray(
|
|
406
|
-
|
|
483
|
+
if (Array.isArray(data)) {
|
|
484
|
+
data.map(function (s) {
|
|
407
485
|
// Select values
|
|
408
486
|
if (newValue.indexOf(s.value) !== -1) {
|
|
409
487
|
s.selected = true;
|
|
@@ -418,7 +496,7 @@ if (!Modal && typeof (require) === 'function') {
|
|
|
418
496
|
updateLabel();
|
|
419
497
|
|
|
420
498
|
// Component onchange
|
|
421
|
-
if (typeof
|
|
499
|
+
if (! ignoreEvent && typeof(onchange) === 'function') {
|
|
422
500
|
onchange.call(self, self, getValue());
|
|
423
501
|
}
|
|
424
502
|
}
|
|
@@ -444,7 +522,7 @@ if (!Modal && typeof (require) === 'function') {
|
|
|
444
522
|
// Reset search
|
|
445
523
|
if (self.autocomplete) {
|
|
446
524
|
// Go to begin of the data
|
|
447
|
-
self.rows =
|
|
525
|
+
self.rows = data;
|
|
448
526
|
// Remove editable attribute
|
|
449
527
|
self.input.removeAttribute('contenteditable');
|
|
450
528
|
// Clear input
|
|
@@ -498,6 +576,26 @@ if (!Modal && typeof (require) === 'function') {
|
|
|
498
576
|
}
|
|
499
577
|
}
|
|
500
578
|
|
|
579
|
+
const loadData = function(result) {
|
|
580
|
+
// Loading controls
|
|
581
|
+
lazyloading = lazyLoading(self);
|
|
582
|
+
// Loading new data from a remote source
|
|
583
|
+
if (result) {
|
|
584
|
+
result.forEach((v) => {
|
|
585
|
+
self.data.push(v);
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
// Process the data
|
|
589
|
+
setData();
|
|
590
|
+
// Set value
|
|
591
|
+
if (typeof(self.value) !== 'undefined') {
|
|
592
|
+
setValue(self.value, true);
|
|
593
|
+
}
|
|
594
|
+
// Custom event by the developer
|
|
595
|
+
if (typeof(onload) === 'function') {
|
|
596
|
+
onload(self);
|
|
597
|
+
}
|
|
598
|
+
}
|
|
501
599
|
|
|
502
600
|
self.add = async function (e) {
|
|
503
601
|
if (!self.input.textContent) {
|
|
@@ -526,11 +624,11 @@ if (!Modal && typeof (require) === 'function') {
|
|
|
526
624
|
}
|
|
527
625
|
|
|
528
626
|
// Process the data
|
|
529
|
-
|
|
627
|
+
data.unshift(s);
|
|
530
628
|
// Select the new item
|
|
531
629
|
self.select(e, s);
|
|
532
630
|
// Close dropdown
|
|
533
|
-
self.
|
|
631
|
+
self.search();
|
|
534
632
|
|
|
535
633
|
// Event
|
|
536
634
|
if (typeof (self.oninsert) === 'function') {
|
|
@@ -538,23 +636,22 @@ if (!Modal && typeof (require) === 'function') {
|
|
|
538
636
|
}
|
|
539
637
|
}
|
|
540
638
|
|
|
541
|
-
self.search = function (
|
|
639
|
+
self.search = function () {
|
|
542
640
|
if (self.state && self.autocomplete) {
|
|
543
641
|
// Filter options
|
|
544
|
-
let
|
|
545
|
-
|
|
546
|
-
|
|
642
|
+
let temp;
|
|
643
|
+
let value = self.input.textContent.toLowerCase()
|
|
644
|
+
if (! value) {
|
|
645
|
+
temp = data;
|
|
547
646
|
} else {
|
|
548
|
-
|
|
549
|
-
return item.selected === true ||
|
|
550
|
-
(item.text.toLowerCase().includes(self.input.textContent.toLowerCase())) ||
|
|
551
|
-
(item.group && item.group.toLowerCase().includes(self.input.textContent.toLowerCase()));
|
|
647
|
+
temp = data.filter(item => {
|
|
648
|
+
return item.selected === true || (item.text.toLowerCase().includes(value)) || (item.group && item.group.toLowerCase().includes(value));
|
|
552
649
|
});
|
|
553
650
|
}
|
|
554
651
|
// Cursor
|
|
555
652
|
removeCursor(true);
|
|
556
653
|
// Update the data from the dropdown
|
|
557
|
-
self.rows =
|
|
654
|
+
self.rows = temp;
|
|
558
655
|
}
|
|
559
656
|
}
|
|
560
657
|
|
|
@@ -613,7 +710,11 @@ if (!Modal && typeof (require) === 'function') {
|
|
|
613
710
|
}
|
|
614
711
|
} else {
|
|
615
712
|
if (value[0] === s) {
|
|
616
|
-
|
|
713
|
+
if (self.allowempty === false) {
|
|
714
|
+
s.selected = true;
|
|
715
|
+
} else {
|
|
716
|
+
s.selected = !s.selected;
|
|
717
|
+
}
|
|
617
718
|
} else {
|
|
618
719
|
if (value[0]) {
|
|
619
720
|
value[0].selected = false;
|
|
@@ -631,14 +732,6 @@ if (!Modal && typeof (require) === 'function') {
|
|
|
631
732
|
}
|
|
632
733
|
}
|
|
633
734
|
|
|
634
|
-
self.getGroup = function () {
|
|
635
|
-
if (this.group && this.header) {
|
|
636
|
-
return this.group;
|
|
637
|
-
} else {
|
|
638
|
-
return '';
|
|
639
|
-
}
|
|
640
|
-
}
|
|
641
|
-
|
|
642
735
|
self.onload = function () {
|
|
643
736
|
if (self.type !== "inline") {
|
|
644
737
|
// Create modal instance
|
|
@@ -661,36 +754,9 @@ if (!Modal && typeof (require) === 'function') {
|
|
|
661
754
|
self.input.remove();
|
|
662
755
|
}
|
|
663
756
|
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
}
|
|
667
|
-
|
|
668
|
-
if (self.url && self.data.length === 0) {
|
|
669
|
-
const xhr = new XMLHttpRequest();
|
|
670
|
-
|
|
671
|
-
xhr.onreadystatechange = function () {
|
|
672
|
-
if (xhr.readyState === 4) {
|
|
673
|
-
if (xhr.status === 200) {
|
|
674
|
-
self.data = JSON.parse(xhr.responseText);
|
|
675
|
-
} else {
|
|
676
|
-
console.error('Failed to fetch data. Status code: ' + xhr.status);
|
|
677
|
-
}
|
|
678
|
-
}
|
|
679
|
-
};
|
|
680
|
-
|
|
681
|
-
xhr.open('GET', self.url, true);
|
|
682
|
-
xhr.setRequestHeader('Content-Type', 'text/json')
|
|
683
|
-
xhr.send();
|
|
684
|
-
}
|
|
757
|
+
// Default width
|
|
758
|
+
self.el.style.width = self.width + 'px';
|
|
685
759
|
|
|
686
|
-
// Loading controls
|
|
687
|
-
lazyloading = lazyLoading(self);
|
|
688
|
-
// Process the data
|
|
689
|
-
setData();
|
|
690
|
-
// Set value
|
|
691
|
-
if (typeof (self.value) !== 'undefined') {
|
|
692
|
-
setValue(self.value);
|
|
693
|
-
}
|
|
694
760
|
// Focus out of the component
|
|
695
761
|
self.el.addEventListener('focusout', function (e) {
|
|
696
762
|
if (self.modal) {
|
|
@@ -701,9 +767,10 @@ if (!Modal && typeof (require) === 'function') {
|
|
|
701
767
|
}
|
|
702
768
|
}
|
|
703
769
|
});
|
|
770
|
+
|
|
704
771
|
// Key events
|
|
705
772
|
self.el.addEventListener('keydown', function (e) {
|
|
706
|
-
if (!self.modal.closed) {
|
|
773
|
+
if (! self.modal.closed) {
|
|
707
774
|
let prevent = false;
|
|
708
775
|
if (e.key === 'ArrowUp') {
|
|
709
776
|
moveCursor(-1);
|
|
@@ -724,6 +791,9 @@ if (!Modal && typeof (require) === 'function') {
|
|
|
724
791
|
} else if (e.key === 'Enter') {
|
|
725
792
|
self.select(e, self.rows[cursor]);
|
|
726
793
|
prevent = true;
|
|
794
|
+
} else if (e.key === 'Escape') {
|
|
795
|
+
self.modal.closed = true;
|
|
796
|
+
prevent = true;
|
|
727
797
|
} else {
|
|
728
798
|
if (e.keyCode === 32 && !self.autocomplete) {
|
|
729
799
|
self.select(e, self.rows[cursor]);
|
|
@@ -735,14 +805,21 @@ if (!Modal && typeof (require) === 'function') {
|
|
|
735
805
|
e.stopImmediatePropagation();
|
|
736
806
|
}
|
|
737
807
|
} else {
|
|
738
|
-
if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
|
|
808
|
+
if (e.key === 'ArrowUp' || e.key === 'ArrowDown' || e.key === 'Enter') {
|
|
739
809
|
self.modal.closed = false;
|
|
740
810
|
}
|
|
741
811
|
}
|
|
742
812
|
});
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
813
|
+
|
|
814
|
+
// Load remote data
|
|
815
|
+
if (self.url) {
|
|
816
|
+
fetch(self.url, {
|
|
817
|
+
headers: {
|
|
818
|
+
'Content-Type': 'text/json',
|
|
819
|
+
}
|
|
820
|
+
}).then(r => r.json()).then(loadData);
|
|
821
|
+
} else {
|
|
822
|
+
loadData();
|
|
746
823
|
}
|
|
747
824
|
}
|
|
748
825
|
|
|
@@ -777,7 +854,7 @@ if (!Modal && typeof (require) === 'function') {
|
|
|
777
854
|
|
|
778
855
|
return `<div class="lm-dropdown" data-insert="{{self.insert}}" data-type="{{self.type}}" data-state="{{self.state}}" :value="self.value" :data="self.data">
|
|
779
856
|
<div class="lm-dropdown-header">
|
|
780
|
-
<div class="lm-dropdown-input" onpaste="self.onpaste" oninput="self.search"
|
|
857
|
+
<div class="lm-dropdown-input" onpaste="self.onpaste" oninput="self.search" onmousedown="self.click" placeholder="{{self.placeholder}}" :ref="self.input" tabindex="0"></div>
|
|
781
858
|
<div class="lm-dropdown-add" onmousedown="self.add"></div>
|
|
782
859
|
<div class="lm-dropdown-header-controls">
|
|
783
860
|
<button onclick="self.close" class="lm-dropdown-done">Done</button>
|
|
@@ -786,7 +863,7 @@ if (!Modal && typeof (require) === 'function') {
|
|
|
786
863
|
<div class="lm-dropdown-content">
|
|
787
864
|
<div>
|
|
788
865
|
<div :loop="self.result" :ref="self.container" :rows="self.rows">
|
|
789
|
-
<div class="lm-dropdown-item" onclick="self.parent.select" data-cursor="{{self.cursor}}" data-selected="{{self.selected}}" data-group="{{self.
|
|
866
|
+
<div class="lm-dropdown-item" onclick="self.parent.select" data-cursor="{{self.cursor}}" data-selected="{{self.selected}}" data-group="{{self.header}}">
|
|
790
867
|
<div><img :src="self.image" /><span>{{self.text}}</span></div>
|
|
791
868
|
</div>
|
|
792
869
|
</div>
|
|
@@ -797,6 +874,8 @@ if (!Modal && typeof (require) === 'function') {
|
|
|
797
874
|
|
|
798
875
|
lemonade.setComponents({ Dropdown: Dropdown });
|
|
799
876
|
|
|
877
|
+
lemonade.createWebComponent('dropdown', Dropdown);
|
|
878
|
+
|
|
800
879
|
return function (root, options) {
|
|
801
880
|
if (typeof (root) === 'object') {
|
|
802
881
|
lemonade.render(Dropdown, root, options)
|
package/dist/react.d.ts
CHANGED
|
@@ -6,10 +6,13 @@
|
|
|
6
6
|
import Component from './index';
|
|
7
7
|
|
|
8
8
|
interface Dropdown {
|
|
9
|
+
ref?: MutableRefObject<undefined>;
|
|
9
10
|
(): any
|
|
10
11
|
[key: string]: any
|
|
11
12
|
}
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
type Props = IntrinsicAttributes & Component.Options & Dropdown;
|
|
15
|
+
|
|
16
|
+
declare function Dropdown<Dropdown>(props: Props): any;
|
|
14
17
|
|
|
15
18
|
export default Dropdown;
|
package/dist/style.css
CHANGED
|
@@ -40,12 +40,8 @@
|
|
|
40
40
|
border-radius: 0;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
.lm-dropdown .lm-lazy {
|
|
44
|
-
max-height: 300px;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
43
|
.lm-dropdown-input {
|
|
48
|
-
padding:
|
|
44
|
+
padding: var(--lm-input-padding, 6px) 24px var(--lm-input-padding, 6px) 10px;
|
|
49
45
|
white-space: nowrap;
|
|
50
46
|
overflow: hidden;
|
|
51
47
|
text-overflow: ellipsis;
|
|
@@ -59,6 +55,10 @@
|
|
|
59
55
|
border-radius: 2px;
|
|
60
56
|
}
|
|
61
57
|
|
|
58
|
+
.lm-dropdown-input > br {
|
|
59
|
+
display: none;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
62
|
.lm-dropdown-input:focus {
|
|
63
63
|
outline: 2px solid var(--lm-border-outline, #000);
|
|
64
64
|
outline-offset: -1px;
|
|
@@ -152,7 +152,11 @@
|
|
|
152
152
|
margin-right: 6px;
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
-
.lm-dropdown-item > div > img[src
|
|
155
|
+
.lm-dropdown-item > div > img:not([src]) {
|
|
156
|
+
display: none;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.lm-dropdown-item > div > img[src=""] {
|
|
156
160
|
display: none;
|
|
157
161
|
}
|
|
158
162
|
|
|
@@ -311,7 +315,9 @@
|
|
|
311
315
|
}
|
|
312
316
|
|
|
313
317
|
.lm-dropdown .lm-lazy {
|
|
318
|
+
max-height: 300px;
|
|
314
319
|
scrollbar-width: thin;
|
|
320
|
+
padding-bottom: 5px;
|
|
315
321
|
}
|
|
316
322
|
|
|
317
323
|
.lm-dropdown .lm-lazy::-webkit-scrollbar {
|
package/package.json
CHANGED
|
@@ -14,10 +14,10 @@
|
|
|
14
14
|
"javascript plugins"
|
|
15
15
|
],
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"lemonadejs": "^4.
|
|
18
|
-
"@lemonadejs/modal": "^
|
|
17
|
+
"lemonadejs": "^4.3.3",
|
|
18
|
+
"@lemonadejs/modal": "^3.3.0"
|
|
19
19
|
},
|
|
20
20
|
"main": "dist/index.js",
|
|
21
21
|
"types": "dist/index.d.ts",
|
|
22
|
-
"version": "3.
|
|
22
|
+
"version": "3.6.0"
|
|
23
23
|
}
|