@lemonadejs/modal 2.4.9 → 2.5.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.js CHANGED
@@ -1,504 +1,557 @@
1
- /**
2
- * pin the modal to the left panel
3
- */
4
- if (!lemonade && typeof (require) === 'function') {
5
- var lemonade = require('lemonadejs');
6
- }
7
-
8
- ;(function (global, factory) {
9
- typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
10
- typeof define === 'function' && define.amd ? define(factory) :
11
- global.Modal = factory();
12
- }(this, (function () {
13
-
14
- // References
15
- const modals = [];
16
- // State of the resize and move modal
17
- let state = {};
18
- // Internal controls of the action of resize and move
19
- let controls = {};
20
- // Width of the border
21
- let cornerSize = 10;
22
- // Container with minimized modals
23
- const minimizedModals = [];
24
- // Default z-index for the modals
25
- const defaultZIndex = 20;
26
-
27
- /**
28
- * Send the modal to the front
29
- * @param container
30
- */
31
- const sendToFront = function(container) {
32
- let highestXIndex = defaultZIndex;
33
- for (let i = 0; i < modals.length; i++) {
34
- const zIndex = parseInt(modals[i].el.style.zIndex);
35
- if (zIndex > highestXIndex) {
36
- highestXIndex = zIndex;
37
- }
38
- }
39
- container.style.zIndex = highestXIndex + 1;
40
- }
41
-
42
- /**
43
- * Send modal to the back
44
- * @param container
45
- */
46
- const sendToBack = function(container) {
47
- container.style.zIndex = defaultZIndex;
48
- }
49
-
50
- // Get the coordinates of the action
51
- const getCoords = function(e) {
52
- let x;
53
- let y;
54
-
55
- if (e.changedTouches && e.changedTouches[0]) {
56
- x = e.changedTouches[0].clientX;
57
- y = e.changedTouches[0].clientY;
58
- } else {
59
- x = e.clientX;
60
- y = e.clientY;
61
- }
62
-
63
- return [x,y];
64
- }
65
-
66
- // Get the button status
67
- const getButton = function(e) {
68
- e = e || window.event;
69
- if (e.buttons) {
70
- return e.buttons;
71
- } else if (e.button) {
72
- return e.button;
73
- } else {
74
- return e.which;
75
- }
76
- }
77
-
78
- // Finalize any potential action
79
- const mouseUp = function(e) {
80
- // Finalize all actions
81
- if (typeof(controls.action) === 'function') {
82
- controls.action();
83
- }
84
- // Remove cursor
85
- if (controls.e) {
86
- controls.e.style.cursor = '';
87
- controls.e.classList.remove('moving');
88
- }
89
- // Reset controls
90
- controls = {};
91
- // Reset state controls
92
- state = {
93
- x: null,
94
- y: null,
95
- }
96
- }
97
-
98
- const mouseMove = function(e) {
99
- if (! getButton(e)) {
100
- return false;
101
- }
102
- // Get mouse coordinates
103
- let [x,y] = getCoords(e);
104
-
105
- // Move modal
106
- if (controls.type === 'move') {
107
- if (state && state.x == null && state.y == null) {
108
- state.x = x;
109
- state.y = y;
110
- }
111
-
112
- let dx = x - state.x;
113
- let dy = y - state.y;
114
- let top = controls.e.offsetTop + dy;
115
- let left = controls.e.offsetLeft + dx;
116
-
117
- // Update position
118
- controls.top = top
119
- controls.left = left
120
- controls.e.style.top = top + 'px';
121
- controls.e.style.left = left + 'px';
122
-
123
- state.x = x;
124
- state.y = y;
125
- state.top = top
126
- state.left = left
127
- } else if (controls.type === 'resize') {
128
- let width = null;
129
- let height = null;
130
- let newHeight = null;
131
-
132
- if (controls.d === 'e-resize' || controls.d === 'ne-resize' || controls.d === 'se-resize') {
133
- // Update width
134
- width = controls.w + (x - controls.x);
135
- controls.e.style.width = width + 'px';
136
-
137
- // Update Height
138
- if (e.shiftKey) {
139
- newHeight = (x - controls.x) * (controls.h / controls.w);
140
- height = controls.h + newHeight;
141
- controls.e.style.height = height + 'px';
142
- } else {
143
- newHeight = false;
144
- }
145
- }
146
-
147
- if (! newHeight) {
148
- if (controls.d === 's-resize' || controls.d === 'se-resize' || controls.d === 'sw-resize') {
149
- height = controls.h + (y - controls.y);
150
- controls.e.style.height = height + 'px';
151
- }
152
- }
153
- }
154
- }
155
-
156
- document.addEventListener('mouseup', mouseUp);
157
- document.addEventListener('mousemove', mouseMove);
158
-
159
- // Dispatcher
160
- const Dispatch = function(type, option){
161
- if (typeof this[type] === 'function') {
162
- this[type](this, option)
163
- }
164
- }
165
-
166
- const refreshMinimized = function() {
167
- let items = minimizedModals;
168
- let numOfItems = items.length;
169
- let width = 0;
170
- let height = 5;
171
- for (let i = 0; i < numOfItems; i++) {
172
- let item = items[i];
173
- item.el.style.marginLeft = width;
174
- item.el.style.marginBottom = height;
175
- width += 205;
176
-
177
- if (document.body.offsetWidth - width < 205) {
178
- width = 0;
179
- height += 50;
180
- }
181
- }
182
- }
183
-
184
- const setMini = function(self) {
185
- // Minimize modals
186
- minimizedModals.push(self);
187
- // Refresh positions
188
- refreshMinimized.call(self);
189
- }
190
-
191
- const removeMini = function(self) {
192
- minimizedModals.splice(minimizedModals.indexOf(self), 1);
193
- self.el.style.marginLeft = '';
194
- self.el.style.marginBottom = '';
195
- // Refresh positions
196
- refreshMinimized.call(self);
197
- }
198
-
199
- const adjustTop = function() {
200
- let self = this;
201
- self.el.style.marginTop = '';
202
- let rect = self.el.getBoundingClientRect();
203
- let limit = document.documentElement.clientHeight + window.scrollY - (rect.top + rect.height);
204
- if (limit < 0) {
205
- self.el.style.marginTop = limit - 10 + 'px';
206
- }
207
- }
208
-
209
- const adjustLeft = function() {
210
- let self = this;
211
- let rect = self.el.getBoundingClientRect();
212
- // Make sure component will be visible on page
213
- let limit = document.documentElement.clientWidth - (rect.left + rect.width);
214
- if (limit < 0) {
215
- self.el.style.marginLeft = limit - 10 + 'px';
216
- }
217
- }
218
-
219
- const isTrue = function(e) {
220
- return e === true || e === 1 || e === 'true';
221
- }
222
-
223
- const Modal = function (template) {
224
- let self = this;
225
- let backdrop = null;
226
- // Make sure keep the state as boolean
227
- self.closed = !!self.closed;
228
-
229
- // Keep all modals references
230
- modals.push(self);
231
-
232
- self.back = function() {
233
- sendToBack(self.el);
234
- }
235
- self.front = function() {
236
- sendToFront(self.el);
237
- }
238
-
239
- self.onload = function() {
240
- if (self.url) {
241
- fetch(self.url)
242
- .then(response => response.clone().body)
243
- .then(body => {
244
- let reader = body.getReader();
245
- reader.read().then(function pump({done, value}) {
246
- const decoder = new TextDecoder();
247
- template += decoder.decode(value.buffer);
248
- });
249
- });
250
- }
251
-
252
- // Dimensions
253
- if (self.width) {
254
- self.el.style.width = self.width + 'px';
255
- } else if (self.el.offsetWidth) {
256
- self.width = self.el.offsetWidth;
257
- }
258
- if (self.height) {
259
- self.el.style.height = self.height + 'px';
260
- } else if (self.el.offsetHeight) {
261
- self.height = self.el.offsetHeight;
262
- }
263
- if (self.top) {
264
- self.el.style.top = self.top + 'px';
265
- }
266
- if (self.left) {
267
- self.el.style.left = self.left + 'px';
268
- }
269
-
270
- // Initial centralize
271
- if (self.position === 'center') {
272
- self.top = (window.innerHeight - self.height) / 2;
273
- self.left = (window.innerWidth - self.width) / 2;
274
- }
275
-
276
- // Full screen
277
- if (self.height > 300) {
278
- self.el.classList.add('fullscreen');
279
- }
280
-
281
- // Responsive
282
- if (document.documentElement.clientWidth < 800 && self.responsive !== false) {
283
- self.el.setAttribute('data-responsive', true);
284
- }
285
-
286
- // Backdrop
287
- if (self.backdrop === true) {
288
- backdrop = document.createElement('div');
289
- backdrop.classList.add('lm-modal-backdrop');
290
- backdrop.addEventListener('mousedown', function() {
291
- self.closed = true;
292
- })
293
- }
294
-
295
- // Bring to front on focus
296
- if (self.layers !== false) {
297
- self.el.classList.add('lm-modal-layers');
298
- }
299
-
300
- // Focus out of the component
301
- self.el.addEventListener('focusout', function(e) {
302
- if (isTrue(self['auto-close'])) {
303
- if (!self.el.contains(e.relatedTarget)) {
304
- self.closed = true;
305
- }
306
- }
307
- });
308
-
309
- // Close and stop propagation
310
- document.addEventListener('keydown', (e) => {
311
- if (e.key === 'Escape' && self.closed === false) {
312
- self.closed = true;
313
- e.preventDefault();
314
- e.stopImmediatePropagation();
315
- }
316
- });
317
- }
318
-
319
- self.onchange = function(property) {
320
- if (property === 'closed') {
321
- if (self.closed === false) {
322
- // Focus on the modal
323
- if (self.focus !== false) {
324
- self.el.focus();
325
- }
326
- // Show backdrop
327
- if (backdrop) {
328
- self.el.parentNode.insertBefore(backdrop, self.el);
329
- }
330
- // Animation
331
- if (self.animation) {
332
- self.el.classList.add('lm-modal-animation');
333
- }
334
- } else {
335
- // Hide backdrop
336
- if (backdrop) {
337
- backdrop.remove();
338
- }
339
- if (self.animation) {
340
- self.el.classList.remove('lm-modal-animation');
341
- }
342
- }
343
-
344
- // Call the vents
345
- self.closed ? Dispatch.call(self,'onclose') : Dispatch.call(self,'onopen');
346
- } else if (property === 'top' || property === 'left' || property === 'width' || property === 'height') {
347
- self.el.style[property] = self[property] + 'px';
348
- }
349
-
350
- // Adjust position
351
- if (self.closed === false) {
352
- if (isTrue(self['auto-adjust'])) {
353
- adjustTop.call(self);
354
- adjustLeft.call(self);
355
- }
356
- }
357
- }
358
-
359
- self.mousemove = function(e) {
360
- if (getButton(e)) {
361
- return;
362
- }
363
-
364
- // Root element of the component
365
- let item = self.el;
366
- // Get the position and dimensions
367
- let rect = item.getBoundingClientRect();
368
-
369
- controls.type = null;
370
- controls.d = null;
371
- controls.e = item;
372
- controls.w = rect.width;
373
- controls.h = rect.height;
374
-
375
- // When resizable
376
- if (self.resizable === true) {
377
- if (rect.height - (e.clientY - rect.top) < cornerSize) {
378
- if (rect.width - (e.clientX - rect.left) < cornerSize) {
379
- item.style.cursor = 'se-resize';
380
- } else {
381
- item.style.cursor = 's-resize';
382
- }
383
- } else if (rect.width - (e.clientX - rect.left) < cornerSize) {
384
- item.style.cursor = 'e-resize';
385
- } else {
386
- item.style.cursor = '';
387
- }
388
-
389
- if (item.style.cursor) {
390
- controls.type = 'resize';
391
- controls.d = item.style.cursor;
392
- } else {
393
- controls.type = null;
394
- controls.d = null;
395
- }
396
- }
397
- }
398
-
399
- self.mousedown = function(e) {
400
- // Get mouse coordinates
401
- let [x,y] = getCoords(e);
402
- controls.x = x;
403
- controls.y = y;
404
- // Root element of the component
405
- let item = self.el;
406
- // Get the position and dimensions
407
- let rect = item.getBoundingClientRect();
408
-
409
- controls.e = item;
410
- controls.w = rect.width;
411
- controls.h = rect.height;
412
-
413
- let corner = rect.width - (x - rect.left) < 40 && (y - rect.top) < 40;
414
-
415
- if (isTrue(self.minimizable) && corner === true) {
416
- self.minimized = ! self.minimized;
417
- // Handles minimized modal positioning
418
- if (self.minimized) {
419
- setMini(self);
420
- } else {
421
- removeMini(self);
422
- }
423
- } else if (isTrue(self.closable) && corner === true) {
424
- self.closed = true;
425
- } else if (! self.minimized) {
426
- // If is not minimized
427
- if (controls.type === 'resize') {
428
- // This will be the callback when finalize the resize
429
- controls.action = function () {
430
- self.width = parseInt(item.style.width);
431
- self.height = parseInt(item.style.height);
432
- }
433
- // Make sure the width and height is defined for the modal
434
- if (!item.style.width) {
435
- item.style.width = controls.w + 'px';
436
- }
437
- if (!item.style.height) {
438
- item.style.height = controls.h + 'px';
439
- }
440
-
441
- e.preventDefault();
442
- } else if (isTrue(self.draggable) && self.title && y - rect.top < 40) {
443
- self.left = parseInt(self.el.style.left) + parseInt(self.el.style.marginLeft);
444
- self.top = parseInt(self.el.style.top) + parseInt(self.el.style.marginTop);
445
- self.el.style.marginLeft = 0;
446
- self.el.style.marginTop = 0;
447
- // Action
448
- controls.type = 'move';
449
- // Callback
450
- controls.action = function () {
451
- self.top = parseInt(item.style.top);
452
- self.left = parseInt(item.style.left);
453
- }
454
- controls.e.classList.add('moving');
455
- }
456
- }
457
- }
458
-
459
- self.open = function() {
460
- if (self.closed === true) {
461
- self.closed = false;
462
- }
463
- }
464
-
465
- self.close = function() {
466
- if (self.closed === false) {
467
- self.closed = true;
468
- }
469
- }
470
-
471
- return `<div class="lm-modal" position="{{self.position}}" closed="{{self.closed}}" closable="{{self.closable}}" minimizable="{{self.minimizable}}" minimized="{{self.minimized}}" overflow="{{self.overflow}}" :top="self.top" :left="self.left" :width="self.width" :height="self.height" onmousedown="self.mousedown(e)" onmousemove="self.mousemove(e)" tabindex="-1">
472
- <div class="lm-modal-title" data-icon="{{self.icon}}">{{self.title}}</div>
473
- <div>${template}</div>
474
- </div>`
475
- }
476
-
477
- lemonade.setComponents({ Modal: Modal });
478
-
479
- return function (root, options, template) {
480
- if (typeof(root) === 'object') {
481
- if (! template) {
482
- template = '';
483
- }
484
- // Keep the DOM elements
485
- let elements = [];
486
- while (root.firstChild) {
487
- elements.push(root.firstChild);
488
- root.firstChild.remove();
489
- }
490
- // Create the modal
491
- let e = lemonade.render(Modal, root, options, template);
492
- // Append any elements inside the modal
493
- if (elements.length) {
494
- while (elements[0]) {
495
- e.children[1].appendChild(elements[0]);
496
- elements.shift();
497
- }
498
- }
499
- return options;
500
- } else {
501
- return Modal.call(this, root);
502
- }
503
- }
1
+ /**
2
+ * pin the modal to the left panel
3
+ */
4
+ if (!lemonade && typeof (require) === 'function') {
5
+ var lemonade = require('lemonadejs');
6
+ }
7
+
8
+ ;(function (global, factory) {
9
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
10
+ typeof define === 'function' && define.amd ? define(factory) :
11
+ global.Modal = factory();
12
+ }(this, (function () {
13
+
14
+ // References
15
+ const modals = [];
16
+ // State of the resize and move modal
17
+ let state = {};
18
+ // Internal controls of the action of resize and move
19
+ let controls = {};
20
+ // Width of the border
21
+ let cornerSize = 10;
22
+ // Container with minimized modals
23
+ const minimizedModals = [];
24
+ // Default z-index for the modals
25
+ const defaultZIndex = 20;
26
+
27
+ /**
28
+ * Send the modal to the front
29
+ * @param container
30
+ */
31
+ const sendToFront = function(container) {
32
+ let highestXIndex = defaultZIndex;
33
+ for (let i = 0; i < modals.length; i++) {
34
+ const zIndex = parseInt(modals[i].el.style.zIndex);
35
+ if (zIndex > highestXIndex) {
36
+ highestXIndex = zIndex;
37
+ }
38
+ }
39
+ container.style.zIndex = highestXIndex + 1;
40
+ }
41
+
42
+ /**
43
+ * Send modal to the back
44
+ * @param container
45
+ */
46
+ const sendToBack = function(container) {
47
+ container.style.zIndex = defaultZIndex;
48
+ }
49
+
50
+ // Get the coordinates of the action
51
+ const getCoords = function(e) {
52
+ let x;
53
+ let y;
54
+
55
+ if (e.changedTouches && e.changedTouches[0]) {
56
+ x = e.changedTouches[0].clientX;
57
+ y = e.changedTouches[0].clientY;
58
+ } else {
59
+ x = e.clientX;
60
+ y = e.clientY;
61
+ }
62
+
63
+ return [x,y];
64
+ }
65
+
66
+ // Get the button status
67
+ const getButton = function(e) {
68
+ e = e || window.event;
69
+ if (e.buttons) {
70
+ return e.buttons;
71
+ } else if (e.button) {
72
+ return e.button;
73
+ } else {
74
+ return e.which;
75
+ }
76
+ }
77
+
78
+ // Finalize any potential action
79
+ const mouseUp = function(e) {
80
+ // Finalize all actions
81
+ if (typeof(controls.action) === 'function') {
82
+ controls.action();
83
+ }
84
+ setTimeout(function() {
85
+ // Remove cursor
86
+ if (controls.e) {
87
+ controls.e.style.cursor = '';
88
+ }
89
+ // Reset controls
90
+ controls = {};
91
+ // Reset state controls
92
+ state = {
93
+ x: null,
94
+ y: null,
95
+ }
96
+ }, 0)
97
+ }
98
+
99
+ const mouseMove = function(e) {
100
+ if (! getButton(e)) {
101
+ return false;
102
+ }
103
+ // Get mouse coordinates
104
+ let [x,y] = getCoords(e);
105
+
106
+ // Move modal
107
+ if (controls.type === 'move') {
108
+ if (state && state.x == null && state.y == null) {
109
+ state.x = x;
110
+ state.y = y;
111
+ }
112
+
113
+ let dx = x - state.x;
114
+ let dy = y - state.y;
115
+ let top = controls.e.offsetTop + dy;
116
+ let left = controls.e.offsetLeft + dx;
117
+
118
+ // Update position
119
+ controls.top = top;
120
+ controls.left = left;
121
+ controls.e.style.top = top + 'px';
122
+ controls.e.style.left = left + 'px';
123
+
124
+ state.x = x;
125
+ state.y = y;
126
+ state.top = top
127
+ state.left = left
128
+ } else if (controls.type === 'resize') {
129
+ let width = null;
130
+ let height = null;
131
+ let newHeight = null;
132
+
133
+ if (controls.d === 'e-resize' || controls.d === 'ne-resize' || controls.d === 'se-resize') {
134
+ // Update width
135
+ width = controls.w + (x - controls.x);
136
+ controls.e.style.width = width + 'px';
137
+
138
+ // Update Height
139
+ if (e.shiftKey) {
140
+ newHeight = (x - controls.x) * (controls.h / controls.w);
141
+ height = controls.h + newHeight;
142
+ controls.e.style.height = height + 'px';
143
+ } else {
144
+ newHeight = false;
145
+ }
146
+ }
147
+
148
+ if (! newHeight) {
149
+ if (controls.d === 's-resize' || controls.d === 'se-resize' || controls.d === 'sw-resize') {
150
+ height = controls.h + (y - controls.y);
151
+ controls.e.style.height = height + 'px';
152
+ }
153
+ }
154
+ }
155
+ }
156
+
157
+ document.addEventListener('mouseup', mouseUp);
158
+ document.addEventListener('mousemove', mouseMove);
159
+
160
+ // Dispatcher
161
+ const Dispatch = function(type, option){
162
+ if (typeof this[type] === 'function') {
163
+ this[type](this, option)
164
+ }
165
+ }
166
+
167
+ const refreshMinimized = function() {
168
+ let items = minimizedModals;
169
+ let numOfItems = items.length;
170
+ let width = 10;
171
+ let height = 10;
172
+ let offsetWidth = document.body.offsetWidth;
173
+ let offsetHeight = document.body.offsetHeight;
174
+ for (let i = 0; i < numOfItems; i++) {
175
+ let item = items[i];
176
+ item.el.style.left = width + 'px';
177
+ item.el.style.top = offsetHeight - 30 - height + 'px';
178
+ width += 205;
179
+
180
+ if (offsetWidth - width < 205) {
181
+ width = 10;
182
+ height += 50;
183
+ }
184
+ }
185
+ }
186
+
187
+ const setMini = function(self) {
188
+ // Minimize modals
189
+ minimizedModals.push(self);
190
+ // Refresh positions
191
+ refreshMinimized();
192
+ }
193
+
194
+ const removeMini = function(self) {
195
+ minimizedModals.splice(minimizedModals.indexOf(self), 1);
196
+ self.el.style.top = self.top + 'px';
197
+ self.el.style.left = self.left + 'px';
198
+ // Refresh positions
199
+ refreshMinimized();
200
+ }
201
+
202
+ const adjustVertical = function() {
203
+ let self = this;
204
+ let rect = self.el.getBoundingClientRect();
205
+ let limit = document.documentElement.clientHeight + window.scrollY - (rect.top + rect.height);
206
+ if (limit < 0) {
207
+ return rect.top + (limit - 10);
208
+ } else if (rect.top < 0) {
209
+ return 10;
210
+ }
211
+ }
212
+
213
+ const adjustHorizontal = function() {
214
+ let self = this;
215
+ let rect = self.el.getBoundingClientRect();
216
+ // Make sure component will be visible on page
217
+ let limit = document.documentElement.clientWidth - (rect.left + rect.width);
218
+ if (limit < 0) {
219
+ return rect.left + (limit - 10);
220
+ } else if (rect.left < 0) {
221
+ return 10;
222
+ }
223
+ }
224
+
225
+ const isTrue = function(e) {
226
+ return e === true || e === 1 || e === 'true';
227
+ }
228
+
229
+ const Modal = function (template) {
230
+ let self = this;
231
+ let backdrop = null;
232
+ // Make sure keep the state as boolean
233
+ self.closed = !!self.closed;
234
+
235
+ // Keep all modals references
236
+ modals.push(self);
237
+
238
+ self.back = function() {
239
+ sendToBack(self.el);
240
+ }
241
+ self.front = function() {
242
+ sendToFront(self.el);
243
+ }
244
+
245
+ // Onload method
246
+ let onload = self.onload;
247
+
248
+ // Native lemonade
249
+ self.onload = function() {
250
+ if (self.url) {
251
+ fetch(self.url)
252
+ .then(response => response.clone().body)
253
+ .then(body => {
254
+ let reader = body.getReader();
255
+ reader.read().then(function pump({done, value}) {
256
+ const decoder = new TextDecoder();
257
+ template += decoder.decode(value.buffer);
258
+ });
259
+ });
260
+ }
261
+
262
+ // Dimensions
263
+ if (self.width) {
264
+ self.el.style.width = self.width + 'px';
265
+ }
266
+ if (self.height) {
267
+ self.el.style.height = self.height + 'px';
268
+ }
269
+
270
+ // Initial centralize
271
+ if (! self.position) {
272
+ if (! self.width && self.el.offsetWidth) {
273
+ self.width = self.el.offsetWidth;
274
+ }
275
+ if (! self.height && self.el.offsetHeight) {
276
+ self.height = self.el.offsetHeight;
277
+ }
278
+ } else if (self.position === 'center') {
279
+ self.top = (window.innerHeight - self.height) / 2;
280
+ self.left = (window.innerWidth - self.width) / 2;
281
+ }
282
+
283
+ // Full screen
284
+ if (self.height > 300) {
285
+ self.el.classList.add('fullscreen');
286
+ }
287
+
288
+ // Responsive
289
+ if (document.documentElement.clientWidth < 800 && self.responsive !== false) {
290
+ self.el.setAttribute('data-responsive', true);
291
+ }
292
+
293
+ // Backdrop
294
+ if (self.backdrop === true) {
295
+ backdrop = document.createElement('div');
296
+ backdrop.classList.add('lm-modal-backdrop');
297
+ backdrop.addEventListener('mousedown', function() {
298
+ self.closed = true;
299
+ })
300
+ }
301
+
302
+ // Adjust position
303
+ if (isTrue(self['auto-adjust'])) {
304
+ let v = adjustVertical.call(self);
305
+ if (v) {
306
+ self.top = v;
307
+ }
308
+ v = adjustHorizontal.call(self);
309
+ if (v) {
310
+ self.left = v;
311
+ }
312
+ }
313
+
314
+ // Bring to front on focus
315
+ if (self.layers !== false) {
316
+ self.el.classList.add('lm-modal-layers');
317
+ }
318
+
319
+ // Focus out of the component
320
+ self.el.addEventListener('focusout', function(e) {
321
+ if (isTrue(self['auto-close'])) {
322
+ if (! self.el.contains(e.relatedTarget)) {
323
+ self.closed = true;
324
+ }
325
+ }
326
+ });
327
+
328
+ // Close and stop propagation
329
+ document.addEventListener('keydown', (e) => {
330
+ if (e.key === 'Escape' && self.closed === false) {
331
+ self.closed = true;
332
+ e.preventDefault();
333
+ e.stopImmediatePropagation();
334
+ }
335
+ });
336
+
337
+ if (typeof(onload) === 'function') {
338
+ Dispatch.call(self, 'onload', self);
339
+ }
340
+ }
341
+
342
+ let ignoreEvents = false;
343
+
344
+ self.onchange = function(property) {
345
+ if (ignoreEvents) {
346
+ return false;
347
+ }
348
+
349
+ if (property === 'closed') {
350
+ if (self.closed === false) {
351
+ // Focus on the modal
352
+ if (self.focus !== false) {
353
+ self.el.focus();
354
+ }
355
+ // Show backdrop
356
+ if (backdrop) {
357
+ self.el.parentNode.insertBefore(backdrop, self.el);
358
+ }
359
+ } else {
360
+ // Hide backdrop
361
+ if (backdrop) {
362
+ backdrop.remove();
363
+ }
364
+ }
365
+
366
+ // Call the vents
367
+ self.closed ? Dispatch.call(self,'onclose',self) : Dispatch.call(self,'onopen',self);
368
+ } else if (property === 'top' || property === 'left' || property === 'width' || property === 'height') {
369
+ if (self[property] !== '') {
370
+ self.el.style[property] = self[property] + 'px';
371
+ } else {
372
+ self.el.style[property] = '';
373
+ }
374
+ } else if (property === 'position') {
375
+ if (self.position) {
376
+ if (self.position === 'center') {
377
+ self.top = (window.innerHeight - self.el.offsetHeight) / 2;
378
+ self.left = (window.innerWidth - self.el.offsetWidth) / 2;
379
+ } else {
380
+ self.top = '';
381
+ self.left = '';
382
+ }
383
+ }
384
+ }
385
+ }
386
+
387
+ self.mousemove = function(e) {
388
+ if (getButton(e)) {
389
+ return;
390
+ }
391
+
392
+ // Root element of the component
393
+ let item = self.el;
394
+ // Get the position and dimensions
395
+ let rect = item.getBoundingClientRect();
396
+
397
+ controls.type = null;
398
+ controls.d = null;
399
+ controls.e = item;
400
+ controls.w = rect.width;
401
+ controls.h = rect.height;
402
+
403
+ // When resizable
404
+ if (self.resizable === true) {
405
+ if (rect.height - (e.clientY - rect.top) < cornerSize) {
406
+ if (rect.width - (e.clientX - rect.left) < cornerSize) {
407
+ item.style.cursor = 'se-resize';
408
+ } else {
409
+ item.style.cursor = 's-resize';
410
+ }
411
+ } else if (rect.width - (e.clientX - rect.left) < cornerSize) {
412
+ item.style.cursor = 'e-resize';
413
+ } else {
414
+ item.style.cursor = '';
415
+ }
416
+
417
+ if (item.style.cursor) {
418
+ controls.type = 'resize';
419
+ controls.d = item.style.cursor;
420
+ } else {
421
+ controls.type = null;
422
+ controls.d = null;
423
+ }
424
+ }
425
+ }
426
+
427
+ self.mousedown = function(e) {
428
+ // Get mouse coordinates
429
+ let [x,y] = getCoords(e);
430
+ controls.x = x;
431
+ controls.y = y;
432
+ // Root element of the component
433
+ let item = self.el;
434
+ // Get the position and dimensions
435
+ let rect = item.getBoundingClientRect();
436
+
437
+ controls.e = item;
438
+ controls.w = rect.width;
439
+ controls.h = rect.height;
440
+
441
+ let corner = (y - rect.top) < 40 && rect.width - (x - rect.left) < 34;
442
+
443
+ // Check if the click in on close
444
+ if (isTrue(self.closable)) {
445
+ if (corner) {
446
+ self.closed = true;
447
+ if (isTrue(self.minimizable)) {
448
+ removeMini(self);
449
+ }
450
+ return;
451
+ }
452
+
453
+ corner = (y - rect.top) < 40 && rect.width - (x - rect.left) < 65;
454
+ }
455
+
456
+ // Check if the click in on minimize
457
+ if (isTrue(self.minimizable)) {
458
+ if (corner) {
459
+ // Minimize
460
+ self.minimized = ! self.minimized;
461
+ // Handles minimized modal positioning
462
+ if (self.minimized) {
463
+ if (! self.top) {
464
+ self.top = self.el.offsetTop;
465
+ }
466
+ if (! self.left) {
467
+ self.left = self.el.offsetLeft;
468
+ }
469
+
470
+ setMini(self);
471
+ } else {
472
+ removeMini(self);
473
+ }
474
+
475
+ return;
476
+ }
477
+ }
478
+
479
+ if (! self.minimized) {
480
+ // If is not minimized
481
+ if (controls.type === 'resize') {
482
+ // Make sure the width and height is defined for the modal
483
+ if (! item.style.width) {
484
+ item.style.width = controls.w + 'px';
485
+ }
486
+ if (! item.style.height) {
487
+ item.style.height = controls.h + 'px';
488
+ }
489
+ // This will be the callback when finalize the resize
490
+ controls.action = function () {
491
+ self.width = parseInt(item.style.width);
492
+ self.height = parseInt(item.style.height);
493
+ controls.e.classList.remove('resizing');
494
+ }
495
+ controls.e.classList.add('resizing');
496
+ } else if (isTrue(self.draggable) && self.title && y - rect.top < 40) {
497
+ // Action
498
+ controls.type = 'move';
499
+ // Callback
500
+ controls.action = function () {
501
+ let v = adjustVertical.call(self) || item.style.top;
502
+ let h = adjustHorizontal.call(self) || item.style.left;
503
+ self.top = parseInt(v);
504
+ self.left = parseInt(h);
505
+ controls.e.classList.remove('moving');
506
+ }
507
+ controls.e.classList.add('moving');
508
+ }
509
+ }
510
+ }
511
+
512
+ self.open = function() {
513
+ if (self.closed === true) {
514
+ self.closed = false;
515
+ }
516
+ }
517
+
518
+ self.close = function() {
519
+ if (self.closed === false) {
520
+ self.closed = true;
521
+ }
522
+ }
523
+
524
+ return `<div class="lm-modal" position="{{self.position}}" closed="{{self.closed}}" closable="{{self.closable}}" minimizable="{{self.minimizable}}" minimized="{{self.minimized}}" overflow="{{self.overflow}}" :top="self.top" :left="self.left" :width="self.width" :height="self.height" onmousedown="self.mousedown(e)" onmousemove="self.mousemove(e)" tabindex="-1">
525
+ <div class="lm-modal-title" data-icon="{{self.icon}}">{{self.title}}</div>
526
+ <div>${template}</div>
527
+ </div>`
528
+ }
529
+
530
+ lemonade.setComponents({ Modal: Modal });
531
+
532
+ return function (root, options, template) {
533
+ if (typeof(root) === 'object') {
534
+ if (! template) {
535
+ template = '';
536
+ }
537
+ // Keep the DOM elements
538
+ let elements = [];
539
+ while (root.firstChild) {
540
+ elements.push(root.firstChild);
541
+ root.firstChild.remove();
542
+ }
543
+ // Create the modal
544
+ let e = lemonade.render(Modal, root, options, template);
545
+ // Append any elements inside the modal
546
+ if (elements.length) {
547
+ while (elements[0]) {
548
+ e.children[1].appendChild(elements[0]);
549
+ elements.shift();
550
+ }
551
+ }
552
+ return options;
553
+ } else {
554
+ return Modal.call(this, root);
555
+ }
556
+ }
504
557
  })));