@lemonadejs/dropdown 3.0.9 → 3.0.12

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 CHANGED
@@ -1,58 +1,70 @@
1
- interface DropdownItem {
2
- /** Value of the selected item. */
3
- value?: string | number;
4
- /** Description of the item */
5
- text?: string;
6
- /** Icon of the item */
7
- image?: string;
8
- /** Name of the group where the item belongs to */
9
- group?: string;
10
- /** Keywords to help finding one item */
11
- synonym?: string[];
12
- /** Item is disabled */
13
- disabled?: boolean;
14
- /** Color for the item */
15
- color?: string;
16
- }
1
+ /**
2
+ * Official Type definitions for LemonadeJS plugins
3
+ * https://lemonadejs.net
4
+ * Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
5
+ */
6
+
7
+ declare function Dropdown(el: HTMLElement, options?: Dropdown.Options): Dropdown.Instance;
8
+
9
+ declare namespace Dropdown {
10
+ interface Item {
11
+ /** Value of the selected item. */
12
+ value?: string | number;
13
+ /** Description of the item */
14
+ text?: string;
15
+ /** Icon of the item */
16
+ image?: string;
17
+ /** Name of the group where the item belongs to */
18
+ group?: string;
19
+ /** Keywords to help finding one item */
20
+ synonym?: string[];
21
+ /** Item is disabled */
22
+ disabled?: boolean;
23
+ /** Color for the item */
24
+ color?: string;
25
+ }
26
+
27
+ interface Options {
28
+ /** Preloaded data items for the dropdown */
29
+ data?: Item[];
30
+ /** Format type of the data, typically { id: name } or { value: text } */
31
+ format?: number;
32
+ /** Indicates if multiple item selection is allowed */
33
+ multiple?: boolean;
34
+ /** Enables the autocomplete feature for user input */
35
+ autocomplete?: boolean;
36
+ /** Rendering style of the dropdown: 'default', 'picker', 'searchbar' or inline */
37
+ type?: 'default' | 'picker' | 'searchbar' | 'inline',
38
+ /** Defines the dropdown's width */
39
+ width?: number;
40
+ /** The initial value of the dropdown */
41
+ value?: string | string[] | number | number[];
42
+ /** Placeholder text for the dropdown */
43
+ placeholder?: string;
44
+ /** Event handler for value changes */
45
+ onchange?: (el: HTMLElement, obj: object, oldValue: string, newValue: string) => void;
46
+ /** Event handler for when the dropdown is ready */
47
+ onload?: (el: HTMLElement, obj: object, data: any, val: any) => void;
48
+ /** Event handler for when the dropdown opens */
49
+ onopen?: (el: HTMLElement) => void;
50
+ /** Event handler for when the dropdown closes */
51
+ onclose?: (el: HTMLElement) => void;
52
+ /** Event handler for when a new option is added to the dropdown */
53
+ oninsert?: (obj: object, item: Item, newItem: Item) => void;
54
+ /** Event handler for just before a new option is added to the dropdown */
55
+ onbeforeinsert?: (obj: object, item: Item) => void;
56
+ /** Event handler for before a search on autocomplete is performed */
57
+ onbeforesearch?: (obj: object, ajaxRequest: object) => boolean | null;
58
+ /** Event handler for processing search results */
59
+ onsearch?: (obj: object, result: object) => void;
60
+ }
17
61
 
18
- interface DropdownOptions {
19
- /** Preloaded data items for the dropdown */
20
- data?: DropdownItem[];
21
- /** Format type of the data, typically { id: name } or { value: text } */
22
- format?: number;
23
- /** Indicates if multiple item selection is allowed */
24
- multiple?: boolean;
25
- /** Enables the autocomplete feature for user input */
26
- autocomplete?: boolean;
27
- /** Rendering style of the dropdown: 'default', 'picker', 'searchbar' or inline */
28
- type?: 'default' | 'picker' | 'searchbar' | 'inline',
29
- /** Defines the dropdown's width */
30
- width?: number;
31
- /** The initial value of the dropdown */
32
- value?: string | string[] | number | number[];
33
- /** Placeholder text for the dropdown */
34
- placeholder?: string;
35
- /** Event handler for value changes */
36
- onchange?: (el: HTMLElement, obj: Dropdown, oldValue: string, newValue: string) => void;
37
- /** Event handler for when the dropdown is ready */
38
- onload?: (el: HTMLElement, obj: Dropdown, data: any, val: any) => void;
39
- /** Event handler for when the dropdown opens */
40
- onopen?: (el: HTMLElement) => void;
41
- /** Event handler for when the dropdown closes */
42
- onclose?: (el: HTMLElement) => void;
43
- /** Event handler for when a new option is added to the dropdown */
44
- oninsert?: (obj: Dropdown, item: DropdownItem, newItem: DropdownItem) => void;
45
- /** Event handler for just before a new option is added to the dropdown */
46
- onbeforeinsert?: (obj: Dropdown, item: DropdownItem) => void;
47
- /** Event handler for before a search on autocomplete is performed */
48
- onbeforesearch?: (obj: Dropdown, ajaxRequest: object) => boolean | null;
49
- /** Event handler for processing search results */
50
- onsearch?: (obj: Dropdown, result: object) => void;
62
+ interface Instance {
63
+ /** Internal type */
64
+ type: 'dropdown';
65
+ /** Current internal value */
66
+ value: Record<number, string>;
67
+ }
51
68
  }
52
69
 
53
- export type Dropdown = (el: HTMLElement, options: DropdownOptions) => {
54
- /** Internal type */
55
- type: 'dropdown';
56
- /** Current internal value */
57
- value: Record<number, string>;
58
- }
70
+ export default Dropdown;
package/dist/index.js CHANGED
@@ -214,6 +214,8 @@ if (!Modal && typeof (require) === 'function') {
214
214
  let adjust = getVisibleRows(false);
215
215
  if (adjust) {
216
216
  el.scrollTop += adjust;
217
+ // Last adjust on the visible rows
218
+ getVisibleRows(false);
217
219
  }
218
220
  }
219
221
 
@@ -237,30 +239,34 @@ if (!Modal && typeof (require) === 'function') {
237
239
  let lazyloading = null;
238
240
 
239
241
  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
242
  // Estimate width
258
243
  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
- });
244
+ // Re-order to make sure groups are in sequence
245
+ if (self.data && self.data.length) {
246
+ self.data.sort((a, b) => {
247
+ // Compare groups
248
+ if (a.group && b.group) {
249
+ return a.group.localeCompare(b.group);
250
+ }
251
+ return 0;
252
+ });
253
+ let group = '';
254
+ // Define group headers
255
+ self.data.map((v) => {
256
+ // Compare groups
257
+ if (v && v.group && v.group !== group) {
258
+ v.header = true;
259
+ group = v.group;
260
+ }
261
+ });
262
+ // Width && values
263
+ self.data.map(function (s) {
264
+ // Estimated width of the element
265
+ if (s.text) {
266
+ width = Math.max(width, s.text.length * 8);
267
+ }
268
+ });
269
+ }
264
270
  // Adjust the width
265
271
  let w = self.input.offsetWidth;
266
272
  if (width < w) {
@@ -389,17 +395,25 @@ if (!Modal && typeof (require) === 'function') {
389
395
  }
390
396
 
391
397
  const getValue = function() {
392
- if (value && value.length) {
393
- return value.filter(v => v.selected).map(i => i.value);
398
+ if (self.multiple) {
399
+ if (value && value.length) {
400
+ return value.filter(v => v.selected).map(i => i.value);
401
+ }
402
+ return [];
403
+ } else {
404
+ if (value && value.length) {
405
+ return value[0].value;
406
+ } else {
407
+ return '';
408
+ }
394
409
  }
395
- return [];
396
410
  }
397
411
 
398
412
  const onclose = function() {
399
413
  // Cursor
400
- removeCursor();
414
+ removeCursor(true);
401
415
  // Reset search
402
- if (self.autocomplete && self.input.textContent) {
416
+ if (self.autocomplete) {
403
417
  // Go to begin of the data
404
418
  self.rows = self.data;
405
419
  // Remove editable attribute
@@ -419,8 +433,6 @@ if (!Modal && typeof (require) === 'function') {
419
433
  self.state = true;
420
434
  // Value
421
435
  let v = value[value.length-1];
422
- // Cursor
423
- removeCursor();
424
436
  // Move to the correct position
425
437
  if (v) {
426
438
  // Go to the last item in the array of values
@@ -462,9 +474,14 @@ if (!Modal && typeof (require) === 'function') {
462
474
  }
463
475
  }
464
476
 
477
+ let timer = null;
478
+
465
479
  self.open = function () {
466
480
  if (self.modal && self.modal.closed) {
481
+ // Open the modal
467
482
  self.modal.closed = false;
483
+ // Timer
484
+ timer = setTimeout(() => timer = null, 400);
468
485
  }
469
486
  }
470
487
 
@@ -472,12 +489,14 @@ if (!Modal && typeof (require) === 'function') {
472
489
  // Close the modal
473
490
  if (self.modal) {
474
491
  self.modal.closed = true;
475
- // Remove cursor
476
- removeCursor(true);
477
492
  }
478
493
  }
479
494
 
480
- self.toggle = function() {
495
+ self.toggle = function(e) {
496
+ if (timer) {
497
+ return;
498
+ }
499
+
481
500
  if (self.modal) {
482
501
  if (self.modal.closed) {
483
502
  self.open();
@@ -487,6 +506,20 @@ if (!Modal && typeof (require) === 'function') {
487
506
  }
488
507
  }
489
508
 
509
+ self.click = function(e) {
510
+ let x;
511
+ if (e.changedTouches && e.changedTouches[0]) {
512
+ x = e.changedTouches[0].clientX;
513
+ } else {
514
+ x = e.clientX;
515
+ }
516
+ if (e.target.offsetWidth - (x - e.target.offsetLeft) < 24) {
517
+ self.toggle();
518
+ } else {
519
+ self.open();
520
+ }
521
+ }
522
+
490
523
  self.select = function(e, s) {
491
524
  if (s) {
492
525
  if (self.multiple === true) {
@@ -533,9 +566,9 @@ if (!Modal && typeof (require) === 'function') {
533
566
  closed: true,
534
567
  focus: false,
535
568
  width: self.width,
536
- 'auto-close': false,
537
569
  onopen: onopen,
538
570
  onclose: onclose,
571
+ 'auto-close': false,
539
572
  };
540
573
  // Generate modal
541
574
  Modal(self.el.children[1], self.modal);
@@ -554,7 +587,7 @@ if (!Modal && typeof (require) === 'function') {
554
587
  if (self.modal) {
555
588
  if (! (e.relatedTarget && self.el.contains(e.relatedTarget)) && !self.el.contains(e.relatedTarget)) {
556
589
  if (! self.modal.closed) {
557
- self.close();
590
+ self.modal.closed = true;
558
591
  }
559
592
  }
560
593
  }
@@ -602,7 +635,7 @@ if (!Modal && typeof (require) === 'function') {
602
635
 
603
636
  return `<div class="lm-dropdown" data-type="{{self.type}}" data-state="{{self.state}}">
604
637
  <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>
638
+ <div class="lm-dropdown-input" oninput="self.search" onfocus="self.open" onclick="self.click" placeholder="{{self.placeholder}}" :ref="self.input" tabindex="0"></div>
606
639
  <button onclick="self.close" class="lm-dropdown-done">Done</button>
607
640
  </div>
608
641
  <div class="lm-dropdown-content">
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Official Type definitions for the LemonadeJS plugins
3
+ * https://lemonadejs.net
4
+ * Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
5
+ */
6
+ import Component from './index';
7
+
8
+ interface Dropdown {
9
+ (): any
10
+ [key: string]: any
11
+ }
12
+
13
+ declare function Dropdown<Dropdown>(props: Component.Options): any;
14
+
15
+ export default Dropdown;
package/dist/style.css CHANGED
@@ -44,13 +44,28 @@
44
44
  cursor: pointer;
45
45
  box-sizing: border-box;
46
46
  width: 100%;
47
- background-repeat: no-repeat;
48
- background-position: top 50% right 0;
49
- background-image: url("data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath d='M7 10l5 5 5-5H7z' fill='gray'/%3E%3C/svg%3E");
50
47
  border: 1px solid #ccc;
51
48
  min-height: 1em;
52
49
  }
53
50
 
51
+ .lm-dropdown-input::after {
52
+ content: '';
53
+ position: absolute;
54
+ width: 24px;
55
+ height: 24px;
56
+ right: 2px;
57
+ top: 2px;
58
+ background-repeat: no-repeat;
59
+ background-image: url("data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath d='M7 10l5 5 5-5H7z' fill='gray'/%3E%3C/svg%3E");
60
+ transition: transform .1s ease-in-out;
61
+ }
62
+
63
+
64
+ .lm-dropdown[data-state="true"] .lm-dropdown-input::after {
65
+ transform: rotate(-180deg);
66
+ }
67
+
68
+
54
69
  .lm-dropdown-input:empty::before {
55
70
  content: "\00a0";
56
71
  }
package/package.json CHANGED
@@ -15,8 +15,9 @@
15
15
  ],
16
16
  "dependencies": {
17
17
  "lemonadejs": "^4.0.7",
18
- "@lemonadejs/modal": "^2.4.0"
18
+ "@lemonadejs/modal": "^2.4.6"
19
19
  },
20
20
  "main": "dist/index.js",
21
- "version": "3.0.9"
21
+ "types": "dist/index.d.ts",
22
+ "version": "3.0.12"
22
23
  }