@lemonadejs/modal 3.3.0 → 5.2.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/README.md +8 -11
- package/dist/index.d.ts +20 -8
- package/dist/index.js +266 -212
- package/dist/style.css +10 -10
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# LemonadeJS Modal
|
|
2
2
|
|
|
3
|
-
[Official website and documentation is here](https://lemonadejs.
|
|
3
|
+
[Official website and documentation is here](https://lemonadejs.com/plugins/modal)
|
|
4
4
|
|
|
5
|
-
Compatible with Vanilla JavaScript, LemonadeJS, React,
|
|
5
|
+
Compatible with Vanilla JavaScript, LemonadeJS, React, VueJS or Angular.
|
|
6
6
|
|
|
7
7
|
The LemonadeJS JavaScript Modal is a responsive and reactive component that creates floating modals. With its flexible settings, users can easily configure draggability, closability, and resizability according to their needs.
|
|
8
8
|
|
|
@@ -36,28 +36,25 @@ To use modal via a CDN, include the following script tags in your HTML file:
|
|
|
36
36
|
|
|
37
37
|
### Usage
|
|
38
38
|
|
|
39
|
-
Declarative
|
|
39
|
+
Declarative—Quick example with Lemonade
|
|
40
40
|
|
|
41
41
|
```javascript
|
|
42
|
-
import lemonade from 'lemonadejs'
|
|
43
42
|
import Modal from '@lemonadejs/modal';
|
|
44
43
|
import '@lemonadejs/modal/dist/style.css';
|
|
45
44
|
|
|
46
45
|
export default function App() {
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
self.toggle = function () {
|
|
50
|
-
self.modalRef.closed = !self.modalRef.closed
|
|
46
|
+
const toggle = () => {
|
|
47
|
+
this.modal.closed = ! this.modal.closed
|
|
51
48
|
}
|
|
52
49
|
|
|
53
|
-
return `<>
|
|
54
|
-
<Modal :center="true" :width="400" :height="200" title="My window modal" :ref="self.
|
|
50
|
+
return render => render`<>
|
|
51
|
+
<Modal :center="true" :width="400" :height="200" title="My window modal" :ref="self.modal">
|
|
55
52
|
<div style="display: flex; flex-direction: column; justify-content: center; padding: 10px;">
|
|
56
53
|
<p>Quick example!</p>
|
|
57
54
|
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor...</div>
|
|
58
55
|
</div>
|
|
59
56
|
</Modal>
|
|
60
|
-
<input type="button" value="Toggle Modal"
|
|
57
|
+
<input type="button" value="Toggle Modal" onclick="${toggle}" />
|
|
61
58
|
</>`
|
|
62
59
|
}
|
|
63
60
|
```
|
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. Absolute change the CSS position to absolute position to respect the screen position */
|
|
26
|
-
position?: 'center' | 'left' | 'right' | 'bottom' | 'absolute' |undefined;
|
|
26
|
+
position?: 'center' | 'left' | 'right' | 'bottom' | 'absolute' | undefined;
|
|
27
27
|
/** Title of the modal */
|
|
28
28
|
title?: string;
|
|
29
29
|
/** Width of the modal */
|
|
@@ -49,15 +49,15 @@ declare namespace Modal {
|
|
|
49
49
|
/** Create scroll when the content is larger than the modal. Default: false */
|
|
50
50
|
overflow?: boolean;
|
|
51
51
|
/** onopen event */
|
|
52
|
-
onopen?: (self:
|
|
53
|
-
/** onclose event */
|
|
54
|
-
onclose?: (self:
|
|
52
|
+
onopen?: (self: Modal.Instance) => void;
|
|
53
|
+
/** onclose event. */
|
|
54
|
+
onclose?: (self: Modal.Instance, origin?: 'button' | 'backdrop' | 'focusout' | 'escape') => void;
|
|
55
55
|
/** onload event */
|
|
56
|
-
onload?: (self:
|
|
56
|
+
onload?: (self: Modal.Instance) => void;
|
|
57
57
|
/** Move event */
|
|
58
|
-
onmove?: (self:
|
|
58
|
+
onmove?: (self: Modal.Instance, x: number, y: number) => void;
|
|
59
59
|
/** Resize event */
|
|
60
|
-
onresize?: (self:
|
|
60
|
+
onresize?: (self: Modal.Instance, w: number, h: number) => void;
|
|
61
61
|
/** Import content from DOM reference */
|
|
62
62
|
content?: HTMLElement;
|
|
63
63
|
}
|
|
@@ -78,7 +78,7 @@ declare namespace Modal {
|
|
|
78
78
|
/** Modal can be moved from its original position. */
|
|
79
79
|
draggable?: boolean;
|
|
80
80
|
/** Modal is automatic align center during initialization */
|
|
81
|
-
position?:
|
|
81
|
+
position?: 'center' | 'left' | 'right' | 'bottom' | 'absolute' | undefined;
|
|
82
82
|
/** Title of the modal */
|
|
83
83
|
title?: string;
|
|
84
84
|
/** Width of the modal */
|
|
@@ -111,6 +111,18 @@ declare namespace Modal {
|
|
|
111
111
|
front: () => void;
|
|
112
112
|
/** Send to back when layers is activated */
|
|
113
113
|
back: () => void;
|
|
114
|
+
/** onopen event */
|
|
115
|
+
onopen?: (self: Modal.Instance) => void;
|
|
116
|
+
/** onclose event */
|
|
117
|
+
onclose?: (self: Modal.Instance, origin?: 'button' | 'backdrop' | 'focusout' | 'escape') => void;
|
|
118
|
+
/** onload event */
|
|
119
|
+
onload?: (self: Modal.Instance) => void;
|
|
120
|
+
/** Move event */
|
|
121
|
+
onmove?: (self: Modal.Instance, x: number, y: number) => void;
|
|
122
|
+
/** Resize event */
|
|
123
|
+
onresize?: (self: Modal.Instance, w: number, h: number) => void;
|
|
124
|
+
/** Import content from DOM reference */
|
|
125
|
+
content?: HTMLElement;
|
|
114
126
|
}
|
|
115
127
|
}
|
|
116
128
|
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* pin the modal to the left panel
|
|
3
3
|
*/
|
|
4
|
-
if (!
|
|
4
|
+
if (!lemonade && typeof (require) === 'function') {
|
|
5
5
|
var lemonade = require('lemonadejs');
|
|
6
6
|
}
|
|
7
7
|
|
|
@@ -11,6 +11,36 @@ if (! lemonade && typeof (require) === 'function') {
|
|
|
11
11
|
global.Modal = factory();
|
|
12
12
|
}(this, (function () {
|
|
13
13
|
|
|
14
|
+
class CustomEvents extends Event {
|
|
15
|
+
constructor(type, props, options) {
|
|
16
|
+
super(type, {
|
|
17
|
+
bubbles: true,
|
|
18
|
+
composed: true,
|
|
19
|
+
...options,
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
if (props) {
|
|
23
|
+
for (const key in props) {
|
|
24
|
+
// Avoid assigning if property already exists anywhere on `this`
|
|
25
|
+
if (! (key in this)) {
|
|
26
|
+
this[key] = props[key];
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Dispatcher
|
|
34
|
+
const Dispatch = function(method, type, options) {
|
|
35
|
+
// Try calling the method directly if provided
|
|
36
|
+
if (typeof method === 'function') {
|
|
37
|
+
let a = Object.values(options);
|
|
38
|
+
return method(...a);
|
|
39
|
+
} else if (this.tagName) {
|
|
40
|
+
this.dispatchEvent(new CustomEvents(type, options));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
14
44
|
// References
|
|
15
45
|
const modals = [];
|
|
16
46
|
// State of the resize and move modal
|
|
@@ -180,22 +210,15 @@ if (! lemonade && typeof (require) === 'function') {
|
|
|
180
210
|
}
|
|
181
211
|
}
|
|
182
212
|
|
|
183
|
-
document
|
|
184
|
-
|
|
213
|
+
if (typeof(document) !== "undefined") {
|
|
214
|
+
document.addEventListener('mouseup', mouseUp);
|
|
215
|
+
document.addEventListener('mousemove', mouseMove);
|
|
216
|
+
}
|
|
185
217
|
|
|
186
218
|
const isTrue = function(e) {
|
|
187
219
|
return e === true || e === 1 || e === 'true';
|
|
188
220
|
}
|
|
189
221
|
|
|
190
|
-
// Dispatcher
|
|
191
|
-
const Dispatch = function(type){
|
|
192
|
-
if (typeof this[type] === 'function') {
|
|
193
|
-
let args = Array.from(arguments);
|
|
194
|
-
args.shift();
|
|
195
|
-
this[type](...args)
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
222
|
const refreshMinimized = function() {
|
|
200
223
|
let items = minimizedModals;
|
|
201
224
|
let numOfItems = items.length;
|
|
@@ -403,7 +426,7 @@ if (! lemonade && typeof (require) === 'function') {
|
|
|
403
426
|
}
|
|
404
427
|
}
|
|
405
428
|
|
|
406
|
-
const Modal = function (template) {
|
|
429
|
+
const Modal = function (template, { onchange, onload }) {
|
|
407
430
|
let self = this;
|
|
408
431
|
let backdrop = null;
|
|
409
432
|
let elements = null;
|
|
@@ -418,190 +441,36 @@ if (! lemonade && typeof (require) === 'function') {
|
|
|
418
441
|
}
|
|
419
442
|
|
|
420
443
|
// Make sure keep the state as boolean
|
|
421
|
-
self.closed = !!self.closed;
|
|
444
|
+
self.closed = !! self.closed;
|
|
422
445
|
|
|
423
446
|
// Keep all modals references
|
|
424
447
|
modals.push(self);
|
|
425
448
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
self.front = function() {
|
|
430
|
-
sendToFront(self.el);
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
// Onload method
|
|
434
|
-
let onload = self.onload;
|
|
435
|
-
|
|
436
|
-
// Native lemonade
|
|
437
|
-
self.onload = function() {
|
|
438
|
-
// Dimensions
|
|
439
|
-
if (self.width) {
|
|
440
|
-
self.el.style.width = self.width + 'px';
|
|
441
|
-
}
|
|
442
|
-
if (self.height) {
|
|
443
|
-
self.el.style.height = self.height + 'px';
|
|
444
|
-
}
|
|
445
|
-
// Position
|
|
446
|
-
if (self.top) {
|
|
447
|
-
self.el.style.top = self.top + 'px';
|
|
448
|
-
}
|
|
449
|
-
if (self.left) {
|
|
450
|
-
self.el.style.left = self.left + 'px';
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
if (self.position === 'absolute' || self.position === 'right' || self.position === 'bottom' || self.position === 'left') {
|
|
454
|
-
|
|
455
|
-
} else {
|
|
456
|
-
if (!self.width && self.el.offsetWidth) {
|
|
457
|
-
self.width = self.el.offsetWidth;
|
|
458
|
-
}
|
|
459
|
-
if (!self.height && self.el.offsetHeight) {
|
|
460
|
-
self.height = self.el.offsetHeight;
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
// Initial centralize
|
|
464
|
-
if (self.position === 'center' || !self.top) {
|
|
465
|
-
self.top = (window.innerHeight - self.height) / 2;
|
|
466
|
-
}
|
|
467
|
-
if (self.position === 'center' || !self.left) {
|
|
468
|
-
self.left = (window.innerWidth - self.width) / 2;
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
// Responsive
|
|
472
|
-
if (document.documentElement.clientWidth < 800) {
|
|
473
|
-
// Full screen
|
|
474
|
-
if (self.height > 300) {
|
|
475
|
-
self.el.classList.add('fullscreen');
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
// Auto adjust
|
|
481
|
-
adjustHorizontal(self);
|
|
482
|
-
adjustVertical(self);
|
|
483
|
-
|
|
484
|
-
// Backdrop
|
|
485
|
-
if (self.backdrop === true) {
|
|
486
|
-
backdrop = document.createElement('div');
|
|
487
|
-
backdrop.classList.add('lm-modal-backdrop');
|
|
488
|
-
backdrop.addEventListener('click', function() {
|
|
489
|
-
self.closed = true;
|
|
490
|
-
});
|
|
491
|
-
|
|
492
|
-
if (self.closed === false) {
|
|
493
|
-
self.el.parentNode.insertBefore(backdrop, self.el);
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
// Bring to front on focus
|
|
498
|
-
if (self.layers !== false) {
|
|
499
|
-
self.el.classList.add('lm-modal-layers');
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
// Import content from DOM
|
|
503
|
-
if (self.content) {
|
|
504
|
-
if (typeof(self.content) === 'string') {
|
|
505
|
-
self.root.appendChild(document.createTextNode(self.content));
|
|
506
|
-
} else if (typeof(self.content.tagName) === 'object' && self.content.tagName) {
|
|
507
|
-
self.root.appendChild(self.content);
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
// Focus out of the component
|
|
512
|
-
self.el.addEventListener('focusout', function(e) {
|
|
513
|
-
if (isTrue(self['auto-close'])) {
|
|
514
|
-
if (! self.el.contains(e.relatedTarget)) {
|
|
515
|
-
self.closed = true;
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
});
|
|
449
|
+
// External onload remove from the lifecycle
|
|
450
|
+
let change = self.onchange;
|
|
451
|
+
self.onchange = null;
|
|
519
452
|
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
if (e.key === 'Escape') {
|
|
523
|
-
if (self.closed === false) {
|
|
524
|
-
self.closed = true;
|
|
525
|
-
e.preventDefault();
|
|
526
|
-
e.stopImmediatePropagation();
|
|
527
|
-
}
|
|
528
|
-
} else if (e.key === 'Enter') {
|
|
529
|
-
self.click(e);
|
|
530
|
-
}
|
|
531
|
-
});
|
|
532
|
-
|
|
533
|
-
// Append elements to the container
|
|
534
|
-
appendElements(self.el.children[1], elements);
|
|
535
|
-
|
|
536
|
-
if (typeof(onload) === 'function') {
|
|
537
|
-
Dispatch.call(self, 'onload', self);
|
|
538
|
-
}
|
|
539
|
-
}
|
|
453
|
+
let load = self.onload;
|
|
454
|
+
self.onload = null;
|
|
540
455
|
|
|
541
456
|
let ignoreEvents = false;
|
|
542
457
|
|
|
543
|
-
|
|
544
|
-
if (
|
|
545
|
-
|
|
458
|
+
const click = function(e) {
|
|
459
|
+
if (e.target.classList.contains('lm-modal-close')) {
|
|
460
|
+
self.close({ origin: 'button' });
|
|
546
461
|
}
|
|
547
462
|
|
|
548
|
-
if (
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
self.el.focus();
|
|
553
|
-
}
|
|
554
|
-
// Show backdrop
|
|
555
|
-
if (backdrop) {
|
|
556
|
-
self.el.parentNode.insertBefore(backdrop, self.el);
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
// Auto adjust
|
|
560
|
-
adjustHorizontal(self);
|
|
561
|
-
adjustVertical(self);
|
|
562
|
-
} else {
|
|
563
|
-
// Hide backdrop
|
|
564
|
-
if (backdrop) {
|
|
565
|
-
backdrop.remove();
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
// Call the vents
|
|
570
|
-
self.closed ? Dispatch.call(self,'onclose',self) : Dispatch.call(self,'onopen',self);
|
|
571
|
-
} else if (property === 'top' || property === 'left' || property === 'width' || property === 'height') {
|
|
572
|
-
if (self[property] !== '') {
|
|
573
|
-
self.el.style[property] = self[property] + 'px';
|
|
574
|
-
} else {
|
|
575
|
-
self.el.style[property] = '';
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
if (property === 'top') {
|
|
579
|
-
adjustVertical(self);
|
|
580
|
-
}
|
|
581
|
-
if (property === 'left') {
|
|
582
|
-
adjustHorizontal(self);
|
|
583
|
-
}
|
|
584
|
-
} else if (property === 'position') {
|
|
585
|
-
if (self.position) {
|
|
586
|
-
if (self.position === 'center') {
|
|
587
|
-
self.top = (window.innerHeight - self.el.offsetHeight) / 2;
|
|
588
|
-
self.left = (window.innerWidth - self.el.offsetWidth) / 2;
|
|
589
|
-
} else {
|
|
590
|
-
self.top = '';
|
|
591
|
-
self.left = '';
|
|
592
|
-
}
|
|
463
|
+
if (e.target.classList.contains('lm-modal-minimize')) {
|
|
464
|
+
// Handles minimized modal positioning
|
|
465
|
+
if (self.minimized === true) {
|
|
466
|
+
removeMini(self);
|
|
593
467
|
} else {
|
|
594
|
-
|
|
595
|
-
self.top = (window.innerHeight - self.el.offsetHeight) / 2;
|
|
596
|
-
}
|
|
597
|
-
if (! self.left) {
|
|
598
|
-
self.left = (window.innerWidth - self.el.offsetWidth) / 2;
|
|
599
|
-
}
|
|
468
|
+
setMini(self);
|
|
600
469
|
}
|
|
601
470
|
}
|
|
602
471
|
}
|
|
603
|
-
|
|
604
|
-
|
|
472
|
+
|
|
473
|
+
const mousemove = function(e) {
|
|
605
474
|
if (getButton(e)) {
|
|
606
475
|
return;
|
|
607
476
|
}
|
|
@@ -622,7 +491,7 @@ if (! lemonade && typeof (require) === 'function') {
|
|
|
622
491
|
controls.l = rect.left;
|
|
623
492
|
|
|
624
493
|
// When resizable
|
|
625
|
-
if (self.resizable
|
|
494
|
+
if (isTrue(self.resizable)) {
|
|
626
495
|
if (e.clientY - rect.top < cornerSize) {
|
|
627
496
|
if (rect.width - (e.clientX - rect.left) < cornerSize) {
|
|
628
497
|
item.style.cursor = 'ne-resize';
|
|
@@ -673,7 +542,7 @@ if (! lemonade && typeof (require) === 'function') {
|
|
|
673
542
|
}
|
|
674
543
|
}
|
|
675
544
|
|
|
676
|
-
|
|
545
|
+
const mousedown = function(e) {
|
|
677
546
|
if (! self.minimized) {
|
|
678
547
|
// Get mouse coordinates
|
|
679
548
|
let [x,y] = getCoords(e);
|
|
@@ -703,7 +572,11 @@ if (! lemonade && typeof (require) === 'function') {
|
|
|
703
572
|
self.height = parseInt(item.style.height);
|
|
704
573
|
controls.e.classList.remove('action');
|
|
705
574
|
// Event
|
|
706
|
-
Dispatch.call(self,
|
|
575
|
+
Dispatch.call(self, self.onresize, 'resize', {
|
|
576
|
+
instance: self,
|
|
577
|
+
width: self.width,
|
|
578
|
+
height: self.height,
|
|
579
|
+
});
|
|
707
580
|
}
|
|
708
581
|
controls.e.classList.add('action');
|
|
709
582
|
} else if (isTrue(self.draggable) && y - rect.top < 40) {
|
|
@@ -712,8 +585,12 @@ if (! lemonade && typeof (require) === 'function') {
|
|
|
712
585
|
self.top = parseInt(item.style.top);
|
|
713
586
|
self.left = parseInt(item.style.left);
|
|
714
587
|
controls.e.classList.remove('action');
|
|
715
|
-
//
|
|
716
|
-
Dispatch.call(self,
|
|
588
|
+
// Open event
|
|
589
|
+
Dispatch.call(self, self.onmove, 'move', {
|
|
590
|
+
instance: self,
|
|
591
|
+
top: self.top,
|
|
592
|
+
left: self.left,
|
|
593
|
+
});
|
|
717
594
|
}
|
|
718
595
|
controls.e.classList.add('action');
|
|
719
596
|
// Remove transform
|
|
@@ -722,43 +599,38 @@ if (! lemonade && typeof (require) === 'function') {
|
|
|
722
599
|
}
|
|
723
600
|
}
|
|
724
601
|
|
|
725
|
-
self.
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
}
|
|
602
|
+
self.back = function() {
|
|
603
|
+
sendToBack(self.el);
|
|
604
|
+
}
|
|
729
605
|
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
if (self.minimized === true) {
|
|
733
|
-
removeMini(self);
|
|
734
|
-
} else {
|
|
735
|
-
setMini(self);
|
|
736
|
-
}
|
|
737
|
-
}
|
|
606
|
+
self.front = function() {
|
|
607
|
+
sendToFront(self.el);
|
|
738
608
|
}
|
|
739
609
|
|
|
740
610
|
self.open = function() {
|
|
741
611
|
if (self.closed === true) {
|
|
742
612
|
self.closed = false;
|
|
613
|
+
console.l
|
|
614
|
+
// Close event
|
|
615
|
+
Dispatch.call(self, self.onopen, 'open', {
|
|
616
|
+
instance: self
|
|
617
|
+
});
|
|
743
618
|
}
|
|
744
619
|
}
|
|
745
620
|
|
|
746
|
-
self.close = function() {
|
|
621
|
+
self.close = function(options) {
|
|
747
622
|
if (self.closed === false) {
|
|
748
623
|
self.closed = true;
|
|
624
|
+
// Close event
|
|
625
|
+
Dispatch.call(self, self.onclose, 'close', {
|
|
626
|
+
instance: self,
|
|
627
|
+
...options
|
|
628
|
+
});
|
|
749
629
|
}
|
|
750
630
|
}
|
|
751
631
|
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
.then(response => response.clone().body)
|
|
755
|
-
.then(body => {
|
|
756
|
-
let reader = body.getReader();
|
|
757
|
-
reader.read().then(function pump({done, value}) {
|
|
758
|
-
const decoder = new TextDecoder();
|
|
759
|
-
self.root.innerHTML = decoder.decode(value.buffer);
|
|
760
|
-
});
|
|
761
|
-
});
|
|
632
|
+
self.isClosed = function() {
|
|
633
|
+
return self.closed;
|
|
762
634
|
}
|
|
763
635
|
|
|
764
636
|
if (! template || typeof(template) !== 'string') {
|
|
@@ -772,7 +644,189 @@ if (! lemonade && typeof (require) === 'function') {
|
|
|
772
644
|
}
|
|
773
645
|
}
|
|
774
646
|
|
|
775
|
-
|
|
647
|
+
// Native lemonade
|
|
648
|
+
onload(() => {
|
|
649
|
+
// Dimensions
|
|
650
|
+
if (self.width) {
|
|
651
|
+
self.el.style.width = self.width + 'px';
|
|
652
|
+
}
|
|
653
|
+
if (self.height) {
|
|
654
|
+
self.el.style.height = self.height + 'px';
|
|
655
|
+
}
|
|
656
|
+
// Position
|
|
657
|
+
if (self.top) {
|
|
658
|
+
self.el.style.top = self.top + 'px';
|
|
659
|
+
}
|
|
660
|
+
if (self.left) {
|
|
661
|
+
self.el.style.left = self.left + 'px';
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
if (self.position === 'absolute' || self.position === 'right' || self.position === 'bottom' || self.position === 'left') {
|
|
665
|
+
|
|
666
|
+
} else {
|
|
667
|
+
if (!self.width && self.el.offsetWidth) {
|
|
668
|
+
self.width = self.el.offsetWidth;
|
|
669
|
+
}
|
|
670
|
+
if (!self.height && self.el.offsetHeight) {
|
|
671
|
+
self.height = self.el.offsetHeight;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
// Initial centralize
|
|
675
|
+
if (self.position === 'center' || !self.top) {
|
|
676
|
+
self.top = (window.innerHeight - self.height) / 2;
|
|
677
|
+
}
|
|
678
|
+
if (self.position === 'center' || !self.left) {
|
|
679
|
+
self.left = (window.innerWidth - self.width) / 2;
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
// Responsive
|
|
683
|
+
if (document.documentElement.clientWidth < 800) {
|
|
684
|
+
// Full screen
|
|
685
|
+
if (self.height > 300) {
|
|
686
|
+
self.el.classList.add('fullscreen');
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
// Auto adjust
|
|
692
|
+
adjustHorizontal(self);
|
|
693
|
+
adjustVertical(self);
|
|
694
|
+
|
|
695
|
+
// Backdrop
|
|
696
|
+
if (self.backdrop === true) {
|
|
697
|
+
backdrop = document.createElement('div');
|
|
698
|
+
backdrop.classList.add('lm-modal-backdrop');
|
|
699
|
+
backdrop.addEventListener('click', () => {
|
|
700
|
+
self.close({ origin: 'backdrop' });
|
|
701
|
+
});
|
|
702
|
+
|
|
703
|
+
if (self.closed === false) {
|
|
704
|
+
self.el.parentNode.insertBefore(backdrop, self.el);
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
// Import content from DOM
|
|
709
|
+
if (self.content) {
|
|
710
|
+
if (typeof(self.content) === 'string') {
|
|
711
|
+
template = self.content;
|
|
712
|
+
} else if (typeof(self.content) === 'object' && self.content.tagName) {
|
|
713
|
+
self.root.appendChild(self.content);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
// Focus out of the component
|
|
718
|
+
self.el.addEventListener('focusout', function(e) {
|
|
719
|
+
if (! self.el.contains(e.relatedTarget)) {
|
|
720
|
+
if (isTrue(self['auto-close'])) {
|
|
721
|
+
self.close({ origin: 'focusout' });
|
|
722
|
+
}
|
|
723
|
+
// Remove focus
|
|
724
|
+
self.el.classList.remove('lm-modal-focus');
|
|
725
|
+
}
|
|
726
|
+
});
|
|
727
|
+
|
|
728
|
+
// Focus out of the component
|
|
729
|
+
self.el.addEventListener('focusin', function(e) {
|
|
730
|
+
self.el.classList.add('lm-modal-focus');
|
|
731
|
+
});
|
|
732
|
+
|
|
733
|
+
// Close and stop propagation
|
|
734
|
+
self.el.addEventListener('keydown', (e) => {
|
|
735
|
+
if (e.key === 'Escape') {
|
|
736
|
+
if (self.closed === false) {
|
|
737
|
+
self.close({ origin: 'escape' });
|
|
738
|
+
e.preventDefault();
|
|
739
|
+
e.stopImmediatePropagation();
|
|
740
|
+
}
|
|
741
|
+
} else if (e.key === 'Enter') {
|
|
742
|
+
click(e);
|
|
743
|
+
}
|
|
744
|
+
});
|
|
745
|
+
|
|
746
|
+
// Append elements to the container
|
|
747
|
+
appendElements(self.el.children[1], elements);
|
|
748
|
+
|
|
749
|
+
if (self.url) {
|
|
750
|
+
fetch(self.url)
|
|
751
|
+
.then(response => response.clone().body)
|
|
752
|
+
.then(body => {
|
|
753
|
+
let reader = body.getReader();
|
|
754
|
+
reader.read().then(({ done, value }) => {
|
|
755
|
+
// Add HTML to the modal
|
|
756
|
+
self.root.innerHTML = new TextDecoder().decode(value.buffer);
|
|
757
|
+
// Call onload event
|
|
758
|
+
Dispatch.call(self, load, 'load', {
|
|
759
|
+
instance: self
|
|
760
|
+
});
|
|
761
|
+
});
|
|
762
|
+
});
|
|
763
|
+
} else {
|
|
764
|
+
// Call onload event
|
|
765
|
+
Dispatch.call(self, load, 'load', {
|
|
766
|
+
instance: self
|
|
767
|
+
});
|
|
768
|
+
}
|
|
769
|
+
});
|
|
770
|
+
|
|
771
|
+
onchange((property) => {
|
|
772
|
+
if (ignoreEvents) {
|
|
773
|
+
return false;
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
if (property === 'closed') {
|
|
777
|
+
if (self.closed === false) {
|
|
778
|
+
// Focus on the modal
|
|
779
|
+
if (self.focus !== false) {
|
|
780
|
+
self.el.focus();
|
|
781
|
+
}
|
|
782
|
+
// Show backdrop
|
|
783
|
+
if (backdrop) {
|
|
784
|
+
self.el.parentNode.insertBefore(backdrop, self.el);
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
// Auto adjust
|
|
788
|
+
adjustHorizontal(self);
|
|
789
|
+
adjustVertical(self);
|
|
790
|
+
} else {
|
|
791
|
+
// Hide backdrop
|
|
792
|
+
if (backdrop) {
|
|
793
|
+
backdrop.remove();
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
} else if (property === 'top' || property === 'left' || property === 'width' || property === 'height') {
|
|
797
|
+
if (self[property] !== '') {
|
|
798
|
+
self.el.style[property] = self[property] + 'px';
|
|
799
|
+
} else {
|
|
800
|
+
self.el.style[property] = '';
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
if (property === 'top') {
|
|
804
|
+
adjustVertical(self);
|
|
805
|
+
}
|
|
806
|
+
if (property === 'left') {
|
|
807
|
+
adjustHorizontal(self);
|
|
808
|
+
}
|
|
809
|
+
} else if (property === 'position') {
|
|
810
|
+
if (self.position) {
|
|
811
|
+
if (self.position === 'center') {
|
|
812
|
+
self.top = (window.innerHeight - self.el.offsetHeight) / 2;
|
|
813
|
+
self.left = (window.innerWidth - self.el.offsetWidth) / 2;
|
|
814
|
+
} else {
|
|
815
|
+
self.top = '';
|
|
816
|
+
self.left = '';
|
|
817
|
+
}
|
|
818
|
+
} else {
|
|
819
|
+
if (! self.top) {
|
|
820
|
+
self.top = (window.innerHeight - self.el.offsetHeight) / 2;
|
|
821
|
+
}
|
|
822
|
+
if (! self.left) {
|
|
823
|
+
self.left = (window.innerWidth - self.el.offsetWidth) / 2;
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
});
|
|
828
|
+
|
|
829
|
+
return render => render`<div class="lm-modal" animation="{{self.animation}}" 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" tabindex="-1" role="modal" onmousedown="${mousedown}" onmousemove="${mousemove}" onclick="${click}">
|
|
776
830
|
<div class="lm-modal-title" data-title="{{self.title}}" data-icon="{{self.icon}}"><div class="lm-modal-icon">{{self.icon}}</div><div>{{self.title}}</div><div class="lm-modal-icon lm-modal-minimize" tabindex="0"></div><div class="lm-modal-icon lm-modal-close" tabindex="0"></div></div>
|
|
777
831
|
<div :ref="self.root">${template}</div>
|
|
778
832
|
</div>`
|
package/dist/style.css
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
.lm-modal {
|
|
2
2
|
position: fixed;
|
|
3
|
-
min-width:
|
|
4
|
-
min-height:
|
|
3
|
+
min-width: 200px;
|
|
4
|
+
min-height: 200px;
|
|
5
5
|
border-radius: 5px;
|
|
6
6
|
z-index: 15;
|
|
7
7
|
background-color: var(--lm-background-color, #fff);
|
|
@@ -28,15 +28,19 @@
|
|
|
28
28
|
.lm-modal-title {
|
|
29
29
|
width: 100%;
|
|
30
30
|
border-bottom: 1px solid var(--lm-border-color, #ccc);
|
|
31
|
-
padding:
|
|
31
|
+
padding: 12px;
|
|
32
32
|
box-sizing: border-box;
|
|
33
|
-
font-size: 1.
|
|
33
|
+
font-size: 1.3em;
|
|
34
34
|
line-height: 24px;
|
|
35
35
|
user-select: none;
|
|
36
36
|
display: flex;
|
|
37
37
|
border-radius: 5px 5px 0 0;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
.lm-modal-focus {
|
|
41
|
+
z-index: 999;
|
|
42
|
+
}
|
|
43
|
+
|
|
40
44
|
.lm-modal > .lm-modal-title {
|
|
41
45
|
display: none;
|
|
42
46
|
}
|
|
@@ -57,9 +61,9 @@
|
|
|
57
61
|
height: 24px;
|
|
58
62
|
font-size: 24px;
|
|
59
63
|
cursor: pointer;
|
|
60
|
-
font-family: "Material Icons";
|
|
64
|
+
font-family: "Material Symbols Outlined", "Material Icons";
|
|
61
65
|
text-align: center;
|
|
62
|
-
margin-right:
|
|
66
|
+
margin-right: 8px;
|
|
63
67
|
display: none;
|
|
64
68
|
}
|
|
65
69
|
|
|
@@ -92,10 +96,6 @@
|
|
|
92
96
|
opacity: 0;
|
|
93
97
|
}
|
|
94
98
|
|
|
95
|
-
.lm-modal-layers:focus {
|
|
96
|
-
z-index: 999;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
99
|
.lm-modal[animation="false"] {
|
|
100
100
|
transition: initial;
|
|
101
101
|
}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"title": "JavaScript Modal",
|
|
4
4
|
"description": "LemonadeJS modal is a JavaScript component to create floating modals.",
|
|
5
5
|
"author": {
|
|
6
|
-
"name": "Contact <contact@lemonadejs.
|
|
6
|
+
"name": "Contact <contact@lemonadejs.com>",
|
|
7
7
|
"url": "https://lemonadejs.net"
|
|
8
8
|
},
|
|
9
9
|
"keywords": [
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
"modal js"
|
|
14
14
|
],
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"lemonadejs": "^
|
|
16
|
+
"lemonadejs": "^5.2.0"
|
|
17
17
|
},
|
|
18
18
|
"main": "dist/index.js",
|
|
19
19
|
"types": "dist/index.d.ts",
|
|
20
|
-
"version": "
|
|
20
|
+
"version": "5.2.0"
|
|
21
21
|
}
|