@lemonadejs/dropdown 2.0.0 → 3.0.4
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 +156 -0
- package/dist/index.js +332 -43
- package/dist/react.js +37 -0
- package/dist/style.css +178 -0
- package/dist/vue.js +45 -0
- package/package.json +23 -22
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
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
|
+
}
|
|
17
|
+
|
|
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', or 'searchbar' */
|
|
28
|
+
type?: 'default' | 'picker' | 'searchbar',
|
|
29
|
+
/** Defines the dropdown's width */
|
|
30
|
+
width?: number;
|
|
31
|
+
/** Determines if the dropdown is opened when initialized */
|
|
32
|
+
opened?: boolean;
|
|
33
|
+
/** The initial value of the dropdown */
|
|
34
|
+
value?: string;
|
|
35
|
+
/** Placeholder text for the dropdown */
|
|
36
|
+
placeholder?: string;
|
|
37
|
+
/** Allows the user to add new options */
|
|
38
|
+
newOptions?: boolean;
|
|
39
|
+
/** Internal controller for the dropdown's position */
|
|
40
|
+
position?: boolean;
|
|
41
|
+
/** Event handler for value changes */
|
|
42
|
+
onchange?: (el: HTMLElement, obj: Dropdown, oldValue: string, newValue: string) => void;
|
|
43
|
+
/** Event handler for when the dropdown is ready */
|
|
44
|
+
onload?: (el: HTMLElement, obj: Dropdown, data: any, val: any) => void;
|
|
45
|
+
/** Event handler for when the dropdown opens */
|
|
46
|
+
onopen?: (el: HTMLElement) => void;
|
|
47
|
+
/** Event handler for when the dropdown closes */
|
|
48
|
+
onclose?: (el: HTMLElement) => void;
|
|
49
|
+
/** Event handler for when the dropdown receives focus */
|
|
50
|
+
onfocus?: (el: HTMLElement) => void;
|
|
51
|
+
/** Event handler for when the dropdown loses focus */
|
|
52
|
+
onblur?: (el: HTMLElement) => void;
|
|
53
|
+
/** Event handler for when a new option is added to the dropdown */
|
|
54
|
+
oninsert?: (obj: Dropdown, item: DropdownItem, newItem: DropdownItem) => void;
|
|
55
|
+
/** Event handler for just before a new option is added to the dropdown */
|
|
56
|
+
onbeforeinsert?: (obj: Dropdown, item: DropdownItem) => void;
|
|
57
|
+
/** Event handler for before a search on autocomplete is performed */
|
|
58
|
+
onbeforesearch?: (obj: Dropdown, ajaxRequest: object) => boolean | null;
|
|
59
|
+
/** Event handler for processing search results */
|
|
60
|
+
onsearch?: (obj: Dropdown, result: object) => void;
|
|
61
|
+
/** Toggles the sorting of dropdown elements */
|
|
62
|
+
sortResults?: boolean;
|
|
63
|
+
/** Indicates if the dropdown should automatically receive focus upon creation */
|
|
64
|
+
autofocus?: boolean;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
interface ItemContainer {
|
|
68
|
+
/** Data for the item */
|
|
69
|
+
data: DropdownItem;
|
|
70
|
+
/** HTML container for the element */
|
|
71
|
+
element: HTMLElement;
|
|
72
|
+
/** HTML container for the group */
|
|
73
|
+
group: HTMLElement;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Toast Plugin */
|
|
77
|
+
export type Dropdown = (el: HTMLElement, options: DropdownOptions) => {
|
|
78
|
+
/** Add a new item to the dropdown */
|
|
79
|
+
add: (title: string, id: string|number) => DropdownItem;
|
|
80
|
+
/** Append new data to the dropdown */
|
|
81
|
+
appendData: (data: DropdownItem[]) => void
|
|
82
|
+
/** Close the dropdown picker */
|
|
83
|
+
closeItem: (ignoreEvents?: boolean) => void
|
|
84
|
+
/** Current selectIndex */
|
|
85
|
+
currentIndex: number;
|
|
86
|
+
/** Find the items with the keyword */
|
|
87
|
+
find: (str: string) => void;
|
|
88
|
+
/** Select the first item */
|
|
89
|
+
first: () => void;
|
|
90
|
+
/** Get all data */
|
|
91
|
+
getData: () => DropdownItem[];
|
|
92
|
+
/** Get the index position of a item by its value */
|
|
93
|
+
getPosition: (value: string) => number | boolean;
|
|
94
|
+
/** Get the text from the selected options */
|
|
95
|
+
getText: (asArray?: boolean) => string | string[];
|
|
96
|
+
/** Get the URL source for the data if defined */
|
|
97
|
+
getUrl: () => string;
|
|
98
|
+
/** Get the value from the selected options */
|
|
99
|
+
getValue: (asArray?: boolean) => string | string[];
|
|
100
|
+
/** DOM Elements for the groups */
|
|
101
|
+
groups: HTMLElement[];
|
|
102
|
+
/** DOM Element for the header */
|
|
103
|
+
header: HTMLElement;
|
|
104
|
+
/** Items */
|
|
105
|
+
items: ItemContainer[];
|
|
106
|
+
/** Move index to the last element in the dropdown */
|
|
107
|
+
last: () => void;
|
|
108
|
+
/** Internal lazy loading method */
|
|
109
|
+
loadDown: () => void;
|
|
110
|
+
/** Internal lazy loading method */
|
|
111
|
+
loadFirst: () => void;
|
|
112
|
+
/** Internal lazy loading method */
|
|
113
|
+
loadLast: () => void;
|
|
114
|
+
/** Internal lazy loading method */
|
|
115
|
+
loadUp: () => void;
|
|
116
|
+
/** Move index to the next element in the dropdown */
|
|
117
|
+
next: () => void;
|
|
118
|
+
/** Open the dropdown */
|
|
119
|
+
open: () => void;
|
|
120
|
+
/** Dropdown configuration */
|
|
121
|
+
options: DropdownOptions;
|
|
122
|
+
/** Move index to the previous element in the dropdown */
|
|
123
|
+
prev: () => void;
|
|
124
|
+
/** Reset the value of the dropdown */
|
|
125
|
+
reset: () => void;
|
|
126
|
+
/** Alias for setCursor */
|
|
127
|
+
resetCursor: (index: number, setPosition?: boolean) => void
|
|
128
|
+
/** Set the value to null */
|
|
129
|
+
resetSelected: () => void;
|
|
130
|
+
/** Array of results when filtering */
|
|
131
|
+
results: DropdownItem[];
|
|
132
|
+
/** Search term */
|
|
133
|
+
search: string;
|
|
134
|
+
/** Select an index */
|
|
135
|
+
selectIndex: (index: number, force?: boolean) => void
|
|
136
|
+
/** Select an item */
|
|
137
|
+
selectItem: (item: DropdownItem) => void;
|
|
138
|
+
/** Set the cursor to a specified element index */
|
|
139
|
+
setCursor: (index: number, setPosition?: boolean) => void
|
|
140
|
+
/** Set new data for the dropdown */
|
|
141
|
+
setData: (items: DropdownItem[]) => void;
|
|
142
|
+
/** Set the id or value for one item */
|
|
143
|
+
setId: (item: number|DropdownItem, newId: number) => void;
|
|
144
|
+
/** Change the dropdown options */
|
|
145
|
+
setOptions: (newOptions: DropdownOptions, reset?: boolean) => void;
|
|
146
|
+
/** Change the dropdown data from a URL */
|
|
147
|
+
setUrl: (newUrl: string, callback?: Function) => void;
|
|
148
|
+
/** Set the value for a dropdown */
|
|
149
|
+
setValue: (newValue: string | string[]) => void;
|
|
150
|
+
/** Internal type */
|
|
151
|
+
type: 'dropdown';
|
|
152
|
+
/** Alias for setCursor */
|
|
153
|
+
updateCursor: (index: number, setPosition?: boolean) => void;
|
|
154
|
+
/** Current internal value */
|
|
155
|
+
value: Record<number, string>;
|
|
156
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -1,44 +1,333 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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
|
+
}
|
|
44
333
|
})));
|
package/dist/react.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import React, { useRef, useEffect } from "react";
|
|
3
|
+
import Component from './index';
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
// @ts-ignore
|
|
7
|
+
export default React.forwardRef((props, mainReference) => {
|
|
8
|
+
// Dom element
|
|
9
|
+
const Ref = useRef(null);
|
|
10
|
+
|
|
11
|
+
// Get the properties for the spreadsheet
|
|
12
|
+
let options = { ...props };
|
|
13
|
+
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
// @ts-ignore
|
|
16
|
+
if (!Ref.current.innerHTML) {
|
|
17
|
+
mainReference.current = Component(Ref.current, options);
|
|
18
|
+
}
|
|
19
|
+
}, []);
|
|
20
|
+
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
for (let key in props) {
|
|
23
|
+
if (props.hasOwnProperty(key) && mainReference.current.hasOwnProperty(key)) {
|
|
24
|
+
if (props[key] !== mainReference.current[key]) {
|
|
25
|
+
mainReference.current[key] = props[key];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}, [props])
|
|
30
|
+
|
|
31
|
+
let prop = {
|
|
32
|
+
ref: Ref,
|
|
33
|
+
style: { height: '100%', width: '100%' }
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
return React.createElement("div", prop);
|
|
37
|
+
})
|
package/dist/style.css
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
.lm-dropdown {
|
|
2
|
+
display: inline-block;
|
|
3
|
+
user-select: none;
|
|
4
|
+
cursor: pointer;
|
|
5
|
+
box-sizing: border-box;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.lm-dropdown .lm-modal {
|
|
9
|
+
padding: 0;
|
|
10
|
+
min-width: initial;
|
|
11
|
+
min-height: 30px;
|
|
12
|
+
border: 1px solid #ccc;
|
|
13
|
+
border-radius: 0;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.lm-dropdown .lm-lazy {
|
|
17
|
+
max-height: 300px;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.lm-dropdown-input {
|
|
21
|
+
display: inline-flex;
|
|
22
|
+
padding: 5px 30px 5px 10px;
|
|
23
|
+
align-items: center;
|
|
24
|
+
position: relative;
|
|
25
|
+
white-space: nowrap;
|
|
26
|
+
overflow: hidden;
|
|
27
|
+
text-overflow: ellipsis;
|
|
28
|
+
appearance: none;
|
|
29
|
+
cursor: pointer;
|
|
30
|
+
box-sizing: border-box;
|
|
31
|
+
width: 100%;
|
|
32
|
+
background-repeat: no-repeat;
|
|
33
|
+
background-position: top 50% right 0;
|
|
34
|
+
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");
|
|
35
|
+
border: 1px solid #ccc;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.lm-dropdown-input:empty::before {
|
|
39
|
+
content: "\00a0";
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.lm-dropdown[data-state="true"] .lm-dropdown-input[placeholder]:empty::before {
|
|
43
|
+
content: "\00a0" attr(placeholder);
|
|
44
|
+
color: #aaa;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.lm-dropdown-options {
|
|
48
|
+
width: 100%;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.lm-dropdown-item {
|
|
52
|
+
box-sizing: border-box;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.lm-dropdown-item[data-group]::before {
|
|
56
|
+
content: attr(data-group);
|
|
57
|
+
display: block;
|
|
58
|
+
padding: 8px;
|
|
59
|
+
font-weight: bold;
|
|
60
|
+
width: 100%;
|
|
61
|
+
background-color: #FFF;
|
|
62
|
+
color: #000;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.lm-dropdown-item > div {
|
|
66
|
+
white-space: nowrap;
|
|
67
|
+
text-align: left;
|
|
68
|
+
text-overflow: ellipsis;
|
|
69
|
+
overflow: hidden;
|
|
70
|
+
color: #000;
|
|
71
|
+
display: flex;
|
|
72
|
+
align-items: center;
|
|
73
|
+
padding: 4px 40px 4px 16px;
|
|
74
|
+
position: relative;
|
|
75
|
+
box-sizing: border-box;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.lm-dropdown-item > div > img {
|
|
79
|
+
width: 24px;
|
|
80
|
+
height: 24px;
|
|
81
|
+
margin-left: -6px;
|
|
82
|
+
margin-right: 6px;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.lm-dropdown-item > div > img[src=''] {
|
|
86
|
+
display: none;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.lm-dropdown-item > div:hover {
|
|
90
|
+
background-color: dodgerblue;
|
|
91
|
+
color: white;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.lm-dropdown-item[data-cursor="true"] > div {
|
|
95
|
+
background-color: #eee;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.lm-dropdown-item[data-selected="true"] > div {
|
|
99
|
+
background-color: dodgerblue;
|
|
100
|
+
color: white;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.lm-dropdown-item[data-selected="true"] > div::after {
|
|
104
|
+
content: '✓';
|
|
105
|
+
position: absolute;
|
|
106
|
+
right: 10px;
|
|
107
|
+
line-height: 24px;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** Picker */
|
|
111
|
+
|
|
112
|
+
.lm-dropdown[data-type="picker"] .lm-modal {
|
|
113
|
+
position: absolute;
|
|
114
|
+
bottom: 0;
|
|
115
|
+
left: 0;
|
|
116
|
+
width: 100% !important;
|
|
117
|
+
height: 300px !important;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.lm-dropdown[data-type="picker"] .lm-dropdown-item > div {
|
|
121
|
+
border-bottom: solid 1px rgba(0, 0, 0, 0.2);
|
|
122
|
+
text-transform: uppercase;
|
|
123
|
+
font-size: 1.1em;
|
|
124
|
+
padding: 16px;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.lm-dropdown[data-type="picker"] .lm-dropdown-item[data-group]::before {
|
|
128
|
+
text-align: center;
|
|
129
|
+
border-bottom: solid 1px rgba(0, 0, 0, 0.2);
|
|
130
|
+
padding: 16px;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/** Searchbar */
|
|
134
|
+
|
|
135
|
+
.lm-dropdown[data-type="searchbar"][data-state="true"] {
|
|
136
|
+
position: absolute;
|
|
137
|
+
top: 0;
|
|
138
|
+
left: 0;
|
|
139
|
+
width: 100% !important;
|
|
140
|
+
height: 100% !important;
|
|
141
|
+
display: flex;
|
|
142
|
+
flex-direction: column;
|
|
143
|
+
background-color: #fff;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.lm-dropdown[data-type="searchbar"][data-state="true"] .lm-dropdown-input {
|
|
147
|
+
font-size: 1.5em;
|
|
148
|
+
border-radius: 0;
|
|
149
|
+
border: 0;
|
|
150
|
+
border-bottom: 1px solid #ccc;
|
|
151
|
+
outline: none;
|
|
152
|
+
background-color: #fff;
|
|
153
|
+
padding-top: 0;
|
|
154
|
+
padding-bottom: 0;
|
|
155
|
+
line-height: 60px;
|
|
156
|
+
height: 60px;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.lm-dropdown[data-type="searchbar"] .lm-modal {
|
|
160
|
+
max-height: initial;
|
|
161
|
+
bottom: 0;
|
|
162
|
+
width: 100% !important;
|
|
163
|
+
height: calc(100% - 60px) !important;
|
|
164
|
+
border: 0;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.lm-dropdown[data-type="searchbar"] .lm-dropdown-item > div {
|
|
168
|
+
border-bottom: solid 1px rgba(0, 0, 0, 0.2);
|
|
169
|
+
text-transform: uppercase;
|
|
170
|
+
font-size: 1.1em;
|
|
171
|
+
padding: 16px;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.lm-dropdown[data-type="searchbar"] .lm-dropdown-item[data-group]::before {
|
|
175
|
+
text-align: center;
|
|
176
|
+
border-bottom: solid 1px rgba(0, 0, 0, 0.2);
|
|
177
|
+
padding: 16px;
|
|
178
|
+
}
|
package/dist/vue.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { h } from 'vue';
|
|
2
|
+
import component from "./index";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
inheritAttrs: false,
|
|
7
|
+
mounted() {
|
|
8
|
+
let options = {
|
|
9
|
+
...this.$attrs
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
this.el = this.$refs.container;
|
|
13
|
+
|
|
14
|
+
this.current = component(this.$refs.container, options);
|
|
15
|
+
},
|
|
16
|
+
setup() {
|
|
17
|
+
let containerProps = {
|
|
18
|
+
ref: 'container',
|
|
19
|
+
style: {
|
|
20
|
+
width: '100%',
|
|
21
|
+
height: '100%',
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
return () => h('div', containerProps);
|
|
25
|
+
},
|
|
26
|
+
watch: {
|
|
27
|
+
$attrs: {
|
|
28
|
+
deep: true,
|
|
29
|
+
handler() {
|
|
30
|
+
this.updateState();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
methods: {
|
|
35
|
+
updateState() {
|
|
36
|
+
for (let key in this.$attrs) {
|
|
37
|
+
if (this.$attrs.hasOwnProperty(key) && this.current.hasOwnProperty(key)) {
|
|
38
|
+
if (this.$attrs[key] !== this.current[key]) {
|
|
39
|
+
this.current[key] = this.$attrs[key];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
package/package.json
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@lemonadejs/dropdown",
|
|
3
|
-
"title": "LemonadeJS dropdown",
|
|
4
|
-
"description": "LemonadeJS dropdown integration.",
|
|
5
|
-
"author": {
|
|
6
|
-
"name": "Contact <contact@lemonadejs.net>",
|
|
7
|
-
"url": "https://lemonadejs.net"
|
|
8
|
-
},
|
|
9
|
-
"keywords": [
|
|
10
|
-
"javascript dropdown",
|
|
11
|
-
"lemonadejs plugins",
|
|
12
|
-
"js",
|
|
13
|
-
"library",
|
|
14
|
-
"javascript plugins"
|
|
15
|
-
],
|
|
16
|
-
"dependencies": {
|
|
17
|
-
"lemonadejs": "^
|
|
18
|
-
"
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"
|
|
22
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@lemonadejs/dropdown",
|
|
3
|
+
"title": "LemonadeJS dropdown",
|
|
4
|
+
"description": "LemonadeJS dropdown integration.",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Contact <contact@lemonadejs.net>",
|
|
7
|
+
"url": "https://lemonadejs.net"
|
|
8
|
+
},
|
|
9
|
+
"keywords": [
|
|
10
|
+
"javascript dropdown",
|
|
11
|
+
"lemonadejs plugins",
|
|
12
|
+
"js",
|
|
13
|
+
"library",
|
|
14
|
+
"javascript plugins"
|
|
15
|
+
],
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"lemonadejs": "^4.0.6",
|
|
18
|
+
"@lemonadejs/modal": "2.3.3",
|
|
19
|
+
"@lemonadejs/lazy-loading": "1.0.0"
|
|
20
|
+
},
|
|
21
|
+
"main": "dist/index.js",
|
|
22
|
+
"version": "3.0.4"
|
|
23
|
+
}
|