@lemonadejs/modal 2.4.10 → 2.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 CHANGED
@@ -23,7 +23,7 @@ declare namespace Modal {
23
23
  /** Modal can be moved from its original position. Default: false */
24
24
  draggable?: boolean;
25
25
  /** Modal is automatic align during initialization */
26
- position?: 'center' | 'left' | 'right' | undefined;
26
+ position?: 'center' | 'left' | 'right' | 'bottom' | undefined;
27
27
  /** Title of the modal */
28
28
  title?: string;
29
29
  /** Width of the modal */
@@ -52,6 +52,8 @@ declare namespace Modal {
52
52
  onopen?: (self: object) => void;
53
53
  /** onclose event */
54
54
  onclose?: (self: object) => void;
55
+ /** onload event */
56
+ onload?: (self: object) => void;
55
57
  }
56
58
 
57
59
  interface Instance {
package/dist/index.js CHANGED
@@ -81,18 +81,19 @@ if (!lemonade && typeof (require) === 'function') {
81
81
  if (typeof(controls.action) === 'function') {
82
82
  controls.action();
83
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
- }
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)
96
97
  }
97
98
 
98
99
  const mouseMove = function(e) {
@@ -166,16 +167,18 @@ if (!lemonade && typeof (require) === 'function') {
166
167
  const refreshMinimized = function() {
167
168
  let items = minimizedModals;
168
169
  let numOfItems = items.length;
169
- let width = 0;
170
- let height = 5;
170
+ let width = 10;
171
+ let height = 55;
172
+ let offsetWidth = window.innerWidth;
173
+ let offsetHeight = window.innerHeight;
171
174
  for (let i = 0; i < numOfItems; i++) {
172
175
  let item = items[i];
173
- item.el.style.marginLeft = width;
174
- item.el.style.marginBottom = height;
176
+ item.el.style.left = width + 'px';
177
+ item.el.style.top = offsetHeight - height + 'px';
175
178
  width += 205;
176
179
 
177
- if (document.body.offsetWidth - width < 205) {
178
- width = 0;
180
+ if (offsetWidth - width < 205) {
181
+ width = 10;
179
182
  height += 50;
180
183
  }
181
184
  }
@@ -184,40 +187,68 @@ if (!lemonade && typeof (require) === 'function') {
184
187
  const setMini = function(self) {
185
188
  // Minimize modals
186
189
  minimizedModals.push(self);
190
+ let rect = self.el.getBoundingClientRect();
191
+ self.minimized = true;
192
+ self.el.top = rect.top;
193
+ self.el.left = rect.left;
194
+ if (! self.el.style.top) {
195
+ self.el.style.top = self.el.top + 'px';
196
+ }
197
+ if (! self.el.style.left) {
198
+ self.el.style.left = self.el.left + 'px';
199
+ }
187
200
  // Refresh positions
188
- refreshMinimized.call(self);
201
+ setTimeout(() => {
202
+ refreshMinimized();
203
+ }, 10);
189
204
  }
190
205
 
191
206
  const removeMini = function(self) {
192
207
  minimizedModals.splice(minimizedModals.indexOf(self), 1);
193
- self.el.style.marginLeft = '';
194
- self.el.style.marginBottom = '';
208
+ self.minimized = false;
209
+ self.el.style.top = self.el.top + 'px';
210
+ self.el.style.left = self.el.left + 'px';
195
211
  // Refresh positions
196
- refreshMinimized.call(self);
212
+ setTimeout(() => {
213
+ refreshMinimized();
214
+ }, 10);
215
+ // Refresh positions
216
+ setTimeout(() => {
217
+ if (self.top === '') {
218
+ self.el.style.top = '';
219
+ }
220
+ if (self.left === '') {
221
+ self.el.style.left = '';
222
+ }
223
+ }, 400);
197
224
  }
198
225
 
199
226
  const adjustVertical = function() {
200
227
  let self = this;
201
- self.el.style.marginTop = '';
202
228
  let rect = self.el.getBoundingClientRect();
203
- let limit = document.documentElement.clientHeight + window.scrollY - (rect.top + rect.height);
229
+ let margin = rect.height >= window.innerHeight || self.position ? 0 : 10;
230
+ // Make sure component will be visible on page
231
+ let limit = window.innerHeight + window.scrollY - (rect.top + rect.height);
204
232
  if (limit < 0) {
205
- self.el.style.marginTop = limit - 10 + 'px';
233
+ return rect.top + (limit - margin);
206
234
  } else if (rect.top < 0) {
207
- self.el.style.marginTop = -1 * rect.top + 10 + 'px';
235
+ return margin;
208
236
  }
237
+ return false;
209
238
  }
210
239
 
211
240
  const adjustHorizontal = function() {
212
241
  let self = this;
213
242
  let rect = self.el.getBoundingClientRect();
243
+ let margin = rect.width >= window.innerWidth || self.position ? 0 : 10;
214
244
  // Make sure component will be visible on page
215
- let limit = document.documentElement.clientWidth - (rect.left + rect.width);
245
+ let limit = window.innerWidth - (rect.left + rect.width);
216
246
  if (limit < 0) {
217
- self.el.style.marginLeft = limit - 10 + 'px';
247
+ return rect.left + (limit - margin);
218
248
  } else if (rect.left < 0) {
219
- self.el.style.marginLeft = -1 * rect.left + 10 + 'px';
249
+ return margin;
220
250
  }
251
+ return false;
221
252
  }
222
253
 
223
254
  const isTrue = function(e) {
@@ -240,6 +271,10 @@ if (!lemonade && typeof (require) === 'function') {
240
271
  sendToFront(self.el);
241
272
  }
242
273
 
274
+ // Onload method
275
+ let onload = self.onload;
276
+
277
+ // Native lemonade
243
278
  self.onload = function() {
244
279
  if (self.url) {
245
280
  fetch(self.url)
@@ -256,14 +291,11 @@ if (!lemonade && typeof (require) === 'function') {
256
291
  // Dimensions
257
292
  if (self.width) {
258
293
  self.el.style.width = self.width + 'px';
259
- } else if (self.el.offsetWidth) {
260
- self.width = self.el.offsetWidth;
261
294
  }
262
295
  if (self.height) {
263
296
  self.el.style.height = self.height + 'px';
264
- } else if (self.el.offsetHeight) {
265
- self.height = self.el.offsetHeight;
266
297
  }
298
+ // Position
267
299
  if (self.top) {
268
300
  self.el.style.top = self.top + 'px';
269
301
  }
@@ -271,20 +303,46 @@ if (!lemonade && typeof (require) === 'function') {
271
303
  self.el.style.left = self.left + 'px';
272
304
  }
273
305
 
274
- // Initial centralize
275
- if (self.position === 'center') {
276
- self.top = (window.innerHeight - self.height) / 2;
277
- self.left = (window.innerWidth - self.width) / 2;
278
- }
306
+ if (self.position === 'right' || self.position === 'bottom' || self.position === 'left') {
279
307
 
280
- // Full screen
281
- if (self.height > 300) {
282
- self.el.classList.add('fullscreen');
283
- }
308
+ } else {
309
+ if (!self.width && self.el.offsetWidth) {
310
+ self.width = self.el.offsetWidth;
311
+ }
312
+ if (!self.height && self.el.offsetHeight) {
313
+ self.height = self.el.offsetHeight;
314
+ }
284
315
 
285
- // Responsive
286
- if (document.documentElement.clientWidth < 800 && self.responsive !== false) {
287
- self.el.setAttribute('data-responsive', true);
316
+ // Initial centralize
317
+ if (self.position === 'center' || !self.top) {
318
+ self.top = (window.innerHeight - self.height) / 2;
319
+ }
320
+ if (self.position === 'center' || !self.left) {
321
+ self.left = (window.innerWidth - self.width) / 2;
322
+ }
323
+
324
+ // Responsive
325
+ if (document.documentElement.clientWidth < 800) {
326
+ if (self.responsive !== false) {
327
+ self.el.setAttribute('data-responsive', true);
328
+ }
329
+ // Full screen
330
+ if (self.height > 300) {
331
+ self.el.classList.add('fullscreen');
332
+ }
333
+ }
334
+
335
+ // Adjust position
336
+ if (isTrue(self['auto-adjust'])) {
337
+ let v = adjustVertical.call(self);
338
+ if (v !== false) {
339
+ self.top = v;
340
+ }
341
+ v = adjustHorizontal.call(self);
342
+ if (v !== false) {
343
+ self.left = v;
344
+ }
345
+ }
288
346
  }
289
347
 
290
348
  // Backdrop
@@ -296,12 +354,6 @@ if (!lemonade && typeof (require) === 'function') {
296
354
  })
297
355
  }
298
356
 
299
- // Adjust position
300
- if (isTrue(self['auto-adjust'])) {
301
- adjustVertical.call(self);
302
- adjustHorizontal.call(self);
303
- }
304
-
305
357
  // Bring to front on focus
306
358
  if (self.layers !== false) {
307
359
  self.el.classList.add('lm-modal-layers');
@@ -310,23 +362,33 @@ if (!lemonade && typeof (require) === 'function') {
310
362
  // Focus out of the component
311
363
  self.el.addEventListener('focusout', function(e) {
312
364
  if (isTrue(self['auto-close'])) {
313
- if (!self.el.contains(e.relatedTarget)) {
365
+ if (! self.el.contains(e.relatedTarget)) {
314
366
  self.closed = true;
315
367
  }
316
368
  }
317
369
  });
318
370
 
319
371
  // Close and stop propagation
320
- document.addEventListener('keydown', (e) => {
372
+ self.el.addEventListener('keydown', (e) => {
321
373
  if (e.key === 'Escape' && self.closed === false) {
322
374
  self.closed = true;
323
375
  e.preventDefault();
324
376
  e.stopImmediatePropagation();
325
377
  }
326
378
  });
379
+
380
+ if (typeof(onload) === 'function') {
381
+ Dispatch.call(self, 'onload', self);
382
+ }
327
383
  }
328
384
 
385
+ let ignoreEvents = false;
386
+
329
387
  self.onchange = function(property) {
388
+ if (ignoreEvents) {
389
+ return false;
390
+ }
391
+
330
392
  if (property === 'closed') {
331
393
  if (self.closed === false) {
332
394
  // Focus on the modal
@@ -337,31 +399,30 @@ if (!lemonade && typeof (require) === 'function') {
337
399
  if (backdrop) {
338
400
  self.el.parentNode.insertBefore(backdrop, self.el);
339
401
  }
340
- // Animation
341
- if (self.animation) {
342
- self.el.classList.add('lm-modal-animation');
343
- }
344
402
  } else {
345
403
  // Hide backdrop
346
404
  if (backdrop) {
347
405
  backdrop.remove();
348
406
  }
349
- if (self.animation) {
350
- self.el.classList.remove('lm-modal-animation');
351
- }
352
407
  }
353
408
 
354
409
  // Call the vents
355
- self.closed ? Dispatch.call(self,'onclose') : Dispatch.call(self,'onopen');
410
+ self.closed ? Dispatch.call(self,'onclose',self) : Dispatch.call(self,'onopen',self);
356
411
  } else if (property === 'top' || property === 'left' || property === 'width' || property === 'height') {
357
- self.el.style[property] = self[property] + 'px';
358
- }
359
-
360
- // Adjust position
361
- if (self.closed === false) {
362
- if (isTrue(self['auto-adjust'])) {
363
- adjustVertical.call(self);
364
- adjustHorizontal.call(self);
412
+ if (self[property] !== '') {
413
+ self.el.style[property] = self[property] + 'px';
414
+ } else {
415
+ self.el.style[property] = '';
416
+ }
417
+ } else if (property === 'position') {
418
+ if (self.position) {
419
+ if (self.position === 'center') {
420
+ self.top = (window.innerHeight - self.el.offsetHeight) / 2;
421
+ self.left = (window.innerWidth - self.el.offsetWidth) / 2;
422
+ } else {
423
+ self.top = '';
424
+ self.left = '';
425
+ }
365
426
  }
366
427
  }
367
428
  }
@@ -420,49 +481,69 @@ if (!lemonade && typeof (require) === 'function') {
420
481
  controls.w = rect.width;
421
482
  controls.h = rect.height;
422
483
 
423
- let corner = rect.width - (x - rect.left) < 40 && (y - rect.top) < 40;
484
+ let corner = (y - rect.top) < 40 && rect.width - (x - rect.left) < 34;
424
485
 
425
- if (isTrue(self.minimizable) && corner === true) {
426
- self.minimized = ! self.minimized;
427
- // Handles minimized modal positioning
428
- if (self.minimized) {
429
- setMini(self);
430
- } else {
431
- removeMini(self);
486
+ // Check if the click in on close
487
+ if (isTrue(self.closable)) {
488
+ if (corner) {
489
+ self.closed = true;
490
+
491
+ if (isTrue(self.minimizable)) {
492
+ removeMini(self);
493
+ }
494
+ return;
432
495
  }
433
- } else if (isTrue(self.closable) && corner === true) {
434
- self.closed = true;
435
- } else if (! self.minimized) {
496
+
497
+ corner = (y - rect.top) < 40 && rect.width - (x - rect.left) < 65;
498
+ }
499
+
500
+ // Check if the click in on minimize
501
+ if (isTrue(self.minimizable)) {
502
+ if (corner) {
503
+ // Handles minimized modal positioning
504
+ if (self.minimized === true) {
505
+ removeMini(self);
506
+ } else {
507
+ setMini(self);
508
+ }
509
+
510
+ return;
511
+ }
512
+ }
513
+
514
+ if (! self.minimized) {
436
515
  // If is not minimized
437
516
  if (controls.type === 'resize') {
438
- // This will be the callback when finalize the resize
439
- controls.action = function () {
440
- self.width = parseInt(item.style.width);
441
- self.height = parseInt(item.style.height);
442
- }
443
517
  // Make sure the width and height is defined for the modal
444
- if (!item.style.width) {
518
+ if (! item.style.width) {
445
519
  item.style.width = controls.w + 'px';
446
520
  }
447
- if (!item.style.height) {
521
+ if (! item.style.height) {
448
522
  item.style.height = controls.h + 'px';
449
523
  }
450
-
451
- e.preventDefault();
524
+ // This will be the callback when finalize the resize
525
+ controls.action = function () {
526
+ self.width = parseInt(item.style.width);
527
+ self.height = parseInt(item.style.height);
528
+ controls.e.classList.remove('resizing');
529
+ }
530
+ controls.e.classList.add('resizing');
452
531
  } else if (isTrue(self.draggable) && self.title && y - rect.top < 40) {
453
- let rect = self.el.getBoundingClientRect();
454
- let top = rect.top;
455
- let left = rect.left;
456
- self.el.style.marginLeft = 0;
457
- self.el.style.marginTop = 0;
458
- self.el.style.top = top + 'px';
459
- self.el.style.left = left + 'px';
460
532
  // Action
461
533
  controls.type = 'move';
462
534
  // Callback
463
535
  controls.action = function () {
464
- self.top = parseInt(item.style.top);
465
- self.left = parseInt(item.style.left);
536
+ let v = adjustVertical.call(self);
537
+ if (v === false) {
538
+ v = parseInt(item.style.top);
539
+ }
540
+ let h = adjustHorizontal.call(self);
541
+ if (v === false) {
542
+ h = parseInt(item.style.left);
543
+ }
544
+ self.top = v;
545
+ self.left = h;
546
+ controls.e.classList.remove('moving');
466
547
  }
467
548
  controls.e.classList.add('moving');
468
549
  }
package/dist/style.css CHANGED
@@ -8,13 +8,13 @@
8
8
  box-sizing: border-box;
9
9
  box-shadow: 0 0 12px rgb(0 0 0 / 22%);
10
10
  opacity: 1;
11
- transition: opacity 0.5s ease;
12
11
  will-change: transform;
13
12
  border: 1px solid #bbb;
14
13
  outline: none;
15
14
  margin: 0;
16
15
  display: flex;
17
16
  flex-direction: column;
17
+ transition: opacity 0.4s ease, top 0.4s ease, left 0.4s ease, width 0.4s ease, height 0.4s ease;
18
18
  }
19
19
 
20
20
  .lm-modal-title {
@@ -75,25 +75,8 @@
75
75
  display: none !important;
76
76
  }
77
77
 
78
- .lm-modal[minimized="true"] {
79
- bottom: 0;
80
- top: initial !important;
81
- left: initial !important;
82
- width: 200px !important;
83
- height: 45px !important;
84
- min-width: initial;
85
- min-height: initial;
86
- overflow: hidden;
87
- transition: margin 0.2s ease-in-out;
88
- }
89
-
90
- .lm-modal[minimized="true"]::after {
91
- content: 'open_in_full';
92
- }
93
-
94
- @keyframes slide-bottom-in {
95
- 0% { transform: translateY(100%); }
96
- 100% { transform: translateY(0%); }
78
+ .lm-modal[minimized="true"]:before {
79
+ content: '\e5d7';
97
80
  }
98
81
 
99
82
  .lm-modal.hide {
@@ -104,11 +87,6 @@
104
87
  z-index: 999;
105
88
  }
106
89
 
107
- .lm-modal-animation {
108
- transform: none;
109
- animation: slide-bottom-in 0.4s forwards;
110
- }
111
-
112
90
  .lm-modal[data-responsive].fullscreen {
113
91
  top: 0;
114
92
  height: 100% !important;
@@ -116,6 +94,11 @@
116
94
 
117
95
  .lm-modal.moving {
118
96
  cursor: move !important;
97
+ transition: initial;
98
+ }
99
+
100
+ .lm-modal.resizing {
101
+ transition: initial;
119
102
  }
120
103
 
121
104
  .lm-modal-backdrop {
@@ -156,17 +139,35 @@
156
139
  top: 0;
157
140
  left: 0;
158
141
  width: 280px;
159
- height: 100vh;
142
+ height: 100vh !important;
160
143
  border-width: 0;
161
144
  border-radius: initial;
162
145
  }
163
146
 
164
147
  .lm-modal[position="right"] {
165
148
  top: 0;
166
- left: initial;
149
+ left: auto;
167
150
  right: 0;
168
151
  width: 280px;
169
- height: 100vh;
152
+ height: 100vh !important;
153
+ border-width: 0;
154
+ border-radius: initial;
155
+ }
156
+
157
+ .lm-modal[position="bottom"] {
158
+ top: initial;
159
+ left: 0;
160
+ bottom: 0;
161
+ width: 100vw !important;
162
+ height: 280px;
170
163
  border-width: 0;
171
164
  border-radius: initial;
165
+ }
166
+
167
+ .lm-modal[minimized="true"] {
168
+ width: 200px !important;
169
+ height: 45px !important;
170
+ min-width: initial;
171
+ min-height: initial;
172
+ overflow: hidden;
172
173
  }
package/package.json CHANGED
@@ -17,5 +17,5 @@
17
17
  },
18
18
  "main": "dist/index.js",
19
19
  "types": "dist/index.d.ts",
20
- "version": "2.4.10"
20
+ "version": "2.6.0"
21
21
  }