@lemonadejs/dropdown 3.0.10 → 3.0.13
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/README.md +89 -0
- package/dist/index.d.ts +67 -55
- package/dist/index.js +58 -26
- package/dist/react.d.ts +15 -0
- package/dist/style.css +1 -1
- package/package.json +3 -2
package/README.md
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# LemonadeJS Dropdown
|
|
2
|
+
|
|
3
|
+
[Official website and documentation is here](https://lemonadejs.net/components/dropdown)
|
|
4
|
+
|
|
5
|
+
Compatible with Vanilla JavaScript, LemonadeJS, React, Vue or Angular.
|
|
6
|
+
|
|
7
|
+
The LemonadeJS Dropdown is a versatile solution for efficient option management. It is a framework-agnostic JavaScript plugin designed for seamless integration with Vue, React, and Angular. This feature-rich dropdown incorporates autocomplete for swift selections, grouping for organized options, and lazy loading for optimized performance, contributing to a smooth and improved user experience.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- Lightweight: The JavaScript Dropdown is only about 2 KBytes;
|
|
12
|
+
- Integration: It can be used as a standalone library or integrated with any modern framework;
|
|
13
|
+
|
|
14
|
+
## Getting Started
|
|
15
|
+
|
|
16
|
+
You can install using NPM or using directly from a CDN.
|
|
17
|
+
|
|
18
|
+
### npm Installation
|
|
19
|
+
|
|
20
|
+
To install it in your project using npm, run the following command:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
$ npm install @lemonadejs/dropdown
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### CDN
|
|
27
|
+
|
|
28
|
+
To use Dropdown via a CDN, include the following script tags in your HTML file:
|
|
29
|
+
|
|
30
|
+
```html
|
|
31
|
+
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/lemonadejs/dist/lemonade.min.js"></script>
|
|
32
|
+
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@lemonadejs/dropdown/dist/index.min.js"></script>
|
|
33
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@lemonadejs/dropdown/dist/style.min.css" />
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Usage
|
|
37
|
+
|
|
38
|
+
Quick example with Lemonade
|
|
39
|
+
|
|
40
|
+
```javascript
|
|
41
|
+
import Dropdown from '@lemonadejs/dropdown';
|
|
42
|
+
import '@lemonadejs/dropdown/dist/style.css'
|
|
43
|
+
import '@lemonadejs/modal/dist/style.css';
|
|
44
|
+
|
|
45
|
+
export default function App() {
|
|
46
|
+
const self = this;
|
|
47
|
+
|
|
48
|
+
self.data = [
|
|
49
|
+
{ text: "Red", value: 1 },
|
|
50
|
+
{ text: "Blue", value: 2 },
|
|
51
|
+
{ text: "Green", value: 3 },
|
|
52
|
+
{ text: "Yellow", value: 4 },
|
|
53
|
+
{ text: "Purple", value: 5 },
|
|
54
|
+
{ text: "Gray", value: 6 },
|
|
55
|
+
]
|
|
56
|
+
|
|
57
|
+
return `<div>
|
|
58
|
+
<Dropdown :data="self.data" :value="1" />
|
|
59
|
+
</div>`
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Settings
|
|
64
|
+
|
|
65
|
+
| Attribute | Description |
|
|
66
|
+
|-----------|-------------|
|
|
67
|
+
| data: Item[] | An array of options to be displayed. Each item should follow the structure defined in the 'Item Details' section. |
|
|
68
|
+
| multiple?: boolean | If provided, enables the multiple selection mode, allowing users to select more than one option simultaneously. |
|
|
69
|
+
| autocomplete?: boolean | If provided, enables the autocomplete feature, displaying an input field that allows users to filter and quickly find options in the Dropdown. |
|
|
70
|
+
| value?: string | Represents the current value or selected option in the Dropdown. |
|
|
71
|
+
| type?: string | Specifies the type of display the Dropdown will use. It can be "searchbar" for a search bar interface, "picker" for a selection picker, or "default" for the default dropdown appearance. |
|
|
72
|
+
|
|
73
|
+
### Item Details
|
|
74
|
+
|
|
75
|
+
| Attribute | Description |
|
|
76
|
+
| --------- | ----------- |
|
|
77
|
+
| value?: number or string | Represents the identifier or unique value associated with the option. |
|
|
78
|
+
| group?: string | Indicates the group to which the option belongs, allowing for segregation and organization. |
|
|
79
|
+
| text?: string | Displays the label or text associated with the option. |
|
|
80
|
+
| image?: string | Specifies the image URL to be displayed alongside the option. |
|
|
81
|
+
|
|
82
|
+
## License
|
|
83
|
+
|
|
84
|
+
The [LemonadeJS](https://lemonadejs.net) LemonadeJS Dropdown is released under the MIT.
|
|
85
|
+
|
|
86
|
+
## Other Tools
|
|
87
|
+
|
|
88
|
+
- [jSuites](https://jsuites.net/v4/)
|
|
89
|
+
- [Jspreadsheet Data Grid](https://jspreadsheet.com)
|
package/dist/index.d.ts
CHANGED
|
@@ -1,58 +1,70 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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?: (obj: object, newValue: string|number) => void;
|
|
46
|
+
/** Event handler for when the dropdown is ready */
|
|
47
|
+
onload?: (obj: object) => void;
|
|
48
|
+
/** Event handler for when the dropdown opens */
|
|
49
|
+
onopen?: (obj: object) => void;
|
|
50
|
+
/** Event handler for when the dropdown closes */
|
|
51
|
+
onclose?: (obj: object) => void;
|
|
52
|
+
/** Event handler for when a new option is added to the dropdown */
|
|
53
|
+
oninsert?: (obj: object, item: 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
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
|
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
|
@@ -238,31 +238,38 @@ if (!Modal && typeof (require) === 'function') {
|
|
|
238
238
|
// Lazy loading global instance
|
|
239
239
|
let lazyloading = null;
|
|
240
240
|
|
|
241
|
+
let onload = self.load;
|
|
242
|
+
let onchange = self.onchange;
|
|
243
|
+
|
|
241
244
|
const setData = function() {
|
|
242
|
-
// Re-order to make sure groups are in sequence
|
|
243
|
-
self.data.sort((a, b) => {
|
|
244
|
-
// Compare groups
|
|
245
|
-
if (a.group && b.group) {
|
|
246
|
-
return a.group.localeCompare(b.group);
|
|
247
|
-
}
|
|
248
|
-
return 0;
|
|
249
|
-
});
|
|
250
|
-
let group = '';
|
|
251
|
-
// Define group headers
|
|
252
|
-
self.data.map((v) => {
|
|
253
|
-
// Compare groups
|
|
254
|
-
if (v.group && v.group !== group) {
|
|
255
|
-
v.header = true;
|
|
256
|
-
group = v.group;
|
|
257
|
-
}
|
|
258
|
-
});
|
|
259
245
|
// Estimate width
|
|
260
246
|
let width = self.width;
|
|
261
|
-
//
|
|
262
|
-
self.data.
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
247
|
+
// Re-order to make sure groups are in sequence
|
|
248
|
+
if (self.data && self.data.length) {
|
|
249
|
+
self.data.sort((a, b) => {
|
|
250
|
+
// Compare groups
|
|
251
|
+
if (a.group && b.group) {
|
|
252
|
+
return a.group.localeCompare(b.group);
|
|
253
|
+
}
|
|
254
|
+
return 0;
|
|
255
|
+
});
|
|
256
|
+
let group = '';
|
|
257
|
+
// Define group headers
|
|
258
|
+
self.data.map((v) => {
|
|
259
|
+
// Compare groups
|
|
260
|
+
if (v && v.group && v.group !== group) {
|
|
261
|
+
v.header = true;
|
|
262
|
+
group = v.group;
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
// Width && values
|
|
266
|
+
self.data.map(function (s) {
|
|
267
|
+
// Estimated width of the element
|
|
268
|
+
if (s.text) {
|
|
269
|
+
width = Math.max(width, s.text.length * 8);
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
}
|
|
266
273
|
// Adjust the width
|
|
267
274
|
let w = self.input.offsetWidth;
|
|
268
275
|
if (width < w) {
|
|
@@ -388,13 +395,26 @@ if (!Modal && typeof (require) === 'function') {
|
|
|
388
395
|
|
|
389
396
|
// Update label
|
|
390
397
|
updateLabel();
|
|
398
|
+
|
|
399
|
+
// Component onchange
|
|
400
|
+
if (typeof(onchange) === 'function') {
|
|
401
|
+
onchange(self, self.value);
|
|
402
|
+
}
|
|
391
403
|
}
|
|
392
404
|
|
|
393
405
|
const getValue = function() {
|
|
394
|
-
if (
|
|
395
|
-
|
|
406
|
+
if (self.multiple) {
|
|
407
|
+
if (value && value.length) {
|
|
408
|
+
return value.filter(v => v.selected).map(i => i.value);
|
|
409
|
+
}
|
|
410
|
+
return [];
|
|
411
|
+
} else {
|
|
412
|
+
if (value && value.length) {
|
|
413
|
+
return value[0].value;
|
|
414
|
+
} else {
|
|
415
|
+
return '';
|
|
416
|
+
}
|
|
396
417
|
}
|
|
397
|
-
return [];
|
|
398
418
|
}
|
|
399
419
|
|
|
400
420
|
const onclose = function() {
|
|
@@ -415,6 +435,10 @@ if (!Modal && typeof (require) === 'function') {
|
|
|
415
435
|
self.value = getValue();
|
|
416
436
|
// Identify the new state of the dropdown
|
|
417
437
|
self.state = false;
|
|
438
|
+
|
|
439
|
+
if (typeof(self.onclose) === 'function') {
|
|
440
|
+
self.onclose(self);
|
|
441
|
+
}
|
|
418
442
|
}
|
|
419
443
|
|
|
420
444
|
const onopen = function() {
|
|
@@ -440,6 +464,10 @@ if (!Modal && typeof (require) === 'function') {
|
|
|
440
464
|
// Focus on the item
|
|
441
465
|
self.input.focus();
|
|
442
466
|
}
|
|
467
|
+
|
|
468
|
+
if (typeof(self.onopen) === 'function') {
|
|
469
|
+
self.onopen(self);
|
|
470
|
+
}
|
|
443
471
|
}
|
|
444
472
|
|
|
445
473
|
self.search = function() {
|
|
@@ -607,6 +635,10 @@ if (!Modal && typeof (require) === 'function') {
|
|
|
607
635
|
e.stopImmediatePropagation();
|
|
608
636
|
}
|
|
609
637
|
});
|
|
638
|
+
|
|
639
|
+
if (typeof(onload) === 'function') {
|
|
640
|
+
onload(self);
|
|
641
|
+
}
|
|
610
642
|
}
|
|
611
643
|
|
|
612
644
|
self.onchange = function(prop) {
|
|
@@ -621,7 +653,7 @@ if (!Modal && typeof (require) === 'function') {
|
|
|
621
653
|
}
|
|
622
654
|
}
|
|
623
655
|
|
|
624
|
-
return `<div class="lm-dropdown" data-type="{{self.type}}" data-state="{{self.state}}">
|
|
656
|
+
return `<div class="lm-dropdown" data-type="{{self.type}}" data-state="{{self.state}}" :value="self.value">
|
|
625
657
|
<div class="lm-dropdown-header">
|
|
626
658
|
<div class="lm-dropdown-input" oninput="self.search" onfocus="self.open" onclick="self.click" placeholder="{{self.placeholder}}" :ref="self.input" tabindex="0"></div>
|
|
627
659
|
<button onclick="self.close" class="lm-dropdown-done">Done</button>
|
package/dist/react.d.ts
ADDED
|
@@ -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
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
top: 2px;
|
|
58
58
|
background-repeat: no-repeat;
|
|
59
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 .
|
|
60
|
+
transition: transform .1s ease-in-out;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
|
package/package.json
CHANGED