@lemonadejs/modal 2.8.0 → 3.1.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
@@ -54,6 +54,8 @@ declare namespace Modal {
54
54
  onclose?: (self: object) => void;
55
55
  /** onload event */
56
56
  onload?: (self: object) => void;
57
+ /** Import content from DOM reference */
58
+ content?: HTMLElement;
57
59
  }
58
60
 
59
61
  interface Instance {
package/dist/index.js CHANGED
@@ -123,33 +123,59 @@ if (!lemonade && typeof (require) === 'function') {
123
123
 
124
124
  state.x = x;
125
125
  state.y = y;
126
- state.top = top
127
- state.left = left
126
+ state.top = top;
127
+ state.left = left;
128
128
  } else if (controls.type === 'resize') {
129
+ let top = null;
130
+ let left = null;
129
131
  let width = null;
130
132
  let height = null;
131
- let newHeight = null;
132
133
 
133
134
  if (controls.d === 'e-resize' || controls.d === 'ne-resize' || controls.d === 'se-resize') {
134
- // Update width
135
135
  width = controls.w + (x - controls.x);
136
- controls.e.style.width = width + 'px';
137
136
 
138
- // Update Height
139
137
  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;
138
+ height = controls.h + (x - controls.x) * (controls.h / controls.w);
139
+ }
140
+ } else if (controls.d === 'w-resize' || controls.d === 'nw-resize'|| controls.d === 'sw-resize') {
141
+ left = controls.l + (x - controls.x);
142
+ // Do not move further
143
+ if (left >= controls.l) {
144
+ left = controls.l;
145
+ }
146
+ // Update width
147
+ width = controls.l + controls.w - left;
148
+ // Consider shift to update height
149
+ if (e.shiftKey) {
150
+ height = controls.h - (x - controls.x) * (controls.h / controls.w);
145
151
  }
146
152
  }
147
153
 
148
- if (! newHeight) {
149
- if (controls.d === 's-resize' || controls.d === 'se-resize' || controls.d === 'sw-resize') {
154
+ if (controls.d === 's-resize' || controls.d === 'se-resize' || controls.d === 'sw-resize') {
155
+ if (! height) {
150
156
  height = controls.h + (y - controls.y);
151
- controls.e.style.height = height + 'px';
152
157
  }
158
+ } else if (controls.d === 'n-resize' || controls.d === 'ne-resize' || controls.d === 'nw-resize') {
159
+ top = controls.t + (y - controls.y);
160
+ // Do not move further
161
+ if (top >= controls.t) {
162
+ top = controls.t;
163
+ }
164
+ // Update height
165
+ height = controls.t + controls.h - top;
166
+ }
167
+
168
+ if (top) {
169
+ controls.e.style.top = top + 'px';
170
+ }
171
+ if (left) {
172
+ controls.e.style.left = left + 'px';
173
+ }
174
+ if (width) {
175
+ controls.e.style.width = width + 'px';
176
+ }
177
+ if (height) {
178
+ controls.e.style.height = height + 'px';
153
179
  }
154
180
  }
155
181
  }
@@ -282,19 +308,21 @@ if (!lemonade && typeof (require) === 'function') {
282
308
  if (self.position === 'absolute') {
283
309
  let w = document.documentElement.offsetWidth;
284
310
  if (w > viewportWidth) {
285
- viewportWidth = w;
311
+ //viewportWidth = w;
286
312
  }
287
313
  } else if (self.position !== 'center') {
288
314
  margin = 0;
289
315
  }
290
316
  }
291
317
 
292
- let rightEdgeDistance = viewportWidth - (self.el.offsetLeft + self.el.offsetWidth);
318
+ let el = self.el.getBoundingClientRect();
319
+
320
+ let rightEdgeDistance = viewportWidth - (el.left + el.width);
293
321
  let transformX = 0;
294
322
 
295
323
  if (self.position === 'absolute') {
296
- if (rightEdgeDistance < 5) {
297
- transformX = (-1 * self.el.offsetWidth) - margin;
324
+ if (rightEdgeDistance < 0) {
325
+ transformX = rightEdgeDistance - margin - 10; // 10 is the scroll width
298
326
  }
299
327
  } else {
300
328
  if (rightEdgeDistance < 0) {
@@ -302,8 +330,8 @@ if (!lemonade && typeof (require) === 'function') {
302
330
  }
303
331
  }
304
332
 
305
- if (self.el.offsetLeft < 0) {
306
- transformX = margin - self.el.offsetLeft;
333
+ if (el.left < 0) {
334
+ transformX = margin - el.left;
307
335
  }
308
336
  if (transformX !== 0) {
309
337
  self.el.style.marginLeft = transformX + 'px';
@@ -323,19 +351,21 @@ if (!lemonade && typeof (require) === 'function') {
323
351
  if (self.position === 'absolute') {
324
352
  let h = document.documentElement.offsetHeight;
325
353
  if (h > viewportHeight) {
326
- viewportHeight = h;
354
+ //viewportHeight = h;
327
355
  }
328
356
  } else if (self.position !== 'center') {
329
357
  margin = 0;
330
358
  }
331
359
  }
332
360
 
333
- let bottomEdgeDistance = viewportHeight - (self.el.offsetTop + self.el.offsetHeight);
361
+ let el = self.el.getBoundingClientRect();
362
+
363
+ let bottomEdgeDistance = viewportHeight - (el.top + el.height);
334
364
  let transformY = 0;
335
365
 
336
366
  if (self.position === 'absolute') {
337
367
  if (bottomEdgeDistance < 5) {
338
- transformY = (-1 * self.el.offsetHeight) - margin;
368
+ transformY = (-1 * el.height) - margin - 20;
339
369
  }
340
370
  } else {
341
371
  if (bottomEdgeDistance < 0) {
@@ -343,17 +373,48 @@ if (!lemonade && typeof (require) === 'function') {
343
373
  }
344
374
  }
345
375
 
346
- if (self.el.offsetTop < 0) {
347
- transformY = margin - self.el.offsetTop;
376
+ if (el.top < 0) {
377
+ transformY = margin - el.top;
348
378
  }
349
379
  if (transformY !== 0) {
350
380
  self.el.style.marginTop = transformY + 'px';
351
381
  }
352
382
  }
353
383
 
384
+ const removeElements = function(root) {
385
+ // Keep the DOM elements
386
+ let elements = [];
387
+ if (root) {
388
+ while (root.firstChild) {
389
+ elements.push(root.firstChild);
390
+ root.firstChild.remove();
391
+ }
392
+ }
393
+ return elements;
394
+ }
395
+
396
+ const appendElements = function(root, elements) {
397
+ if (elements && elements.length) {
398
+ while (elements[0]) {
399
+ root.appendChild(elements.shift());
400
+ }
401
+ }
402
+ }
403
+
354
404
  const Modal = function (template) {
355
405
  let self = this;
356
406
  let backdrop = null;
407
+ let elements = null;
408
+
409
+ if (this.tagName) {
410
+ // Remove elements from the DOM
411
+ elements = removeElements(this);
412
+
413
+ this.addEventListener('dragstart', (e) => {
414
+ e.preventDefault();
415
+ });
416
+ }
417
+
357
418
  // Make sure keep the state as boolean
358
419
  self.closed = !!self.closed;
359
420
 
@@ -444,6 +505,11 @@ if (!lemonade && typeof (require) === 'function') {
444
505
  self.el.classList.add('lm-modal-layers');
445
506
  }
446
507
 
508
+ // Import content from DOM
509
+ if (self.content) {
510
+ self.el.children[1].appendChild(self.content);
511
+ }
512
+
447
513
  // Focus out of the component
448
514
  self.el.addEventListener('focusout', function(e) {
449
515
  if (isTrue(self['auto-close'])) {
@@ -455,13 +521,20 @@ if (!lemonade && typeof (require) === 'function') {
455
521
 
456
522
  // Close and stop propagation
457
523
  self.el.addEventListener('keydown', (e) => {
458
- if (e.key === 'Escape' && self.closed === false) {
459
- self.closed = true;
460
- e.preventDefault();
461
- e.stopImmediatePropagation();
524
+ if (e.key === 'Escape') {
525
+ if (self.closed === false) {
526
+ self.closed = true;
527
+ e.preventDefault();
528
+ e.stopImmediatePropagation();
529
+ }
530
+ } else if (e.key === 'Enter') {
531
+ self.click(e);
462
532
  }
463
533
  });
464
534
 
535
+ // Append elements to the container
536
+ appendElements(self.el.children[1], elements);
537
+
465
538
  if (typeof(onload) === 'function') {
466
539
  Dispatch.call(self, 'onload', self);
467
540
  }
@@ -535,6 +608,8 @@ if (!lemonade && typeof (require) === 'function') {
535
608
  return;
536
609
  }
537
610
 
611
+ // Get mouse coordinates
612
+ let [x,y] = getCoords(e);
538
613
  // Root element of the component
539
614
  let item = self.el;
540
615
  // Get the position and dimensions
@@ -545,17 +620,31 @@ if (!lemonade && typeof (require) === 'function') {
545
620
  controls.e = item;
546
621
  controls.w = rect.width;
547
622
  controls.h = rect.height;
623
+ controls.t = rect.top;
624
+ controls.l = rect.left;
548
625
 
549
626
  // When resizable
550
627
  if (self.resizable === true) {
551
- if (rect.height - (e.clientY - rect.top) < cornerSize) {
628
+ if (e.clientY - rect.top < cornerSize) {
629
+ if (rect.width - (e.clientX - rect.left) < cornerSize) {
630
+ item.style.cursor = 'ne-resize';
631
+ } else if (e.clientX - rect.left < cornerSize) {
632
+ item.style.cursor = 'nw-resize';
633
+ } else {
634
+ item.style.cursor = 'n-resize';
635
+ }
636
+ } else if (rect.height - (e.clientY - rect.top) < cornerSize) {
552
637
  if (rect.width - (e.clientX - rect.left) < cornerSize) {
553
638
  item.style.cursor = 'se-resize';
639
+ } else if (e.clientX - rect.left < cornerSize) {
640
+ item.style.cursor = 'sw-resize';
554
641
  } else {
555
642
  item.style.cursor = 's-resize';
556
643
  }
557
644
  } else if (rect.width - (e.clientX - rect.left) < cornerSize) {
558
645
  item.style.cursor = 'e-resize';
646
+ } else if (e.clientX - rect.left < cornerSize) {
647
+ item.style.cursor = 'w-resize';
559
648
  } else {
560
649
  item.style.cursor = '';
561
650
  }
@@ -568,6 +657,22 @@ if (!lemonade && typeof (require) === 'function') {
568
657
  controls.d = null;
569
658
  }
570
659
  }
660
+
661
+ if (controls.type == null && isTrue(self.draggable)) {
662
+ if (y - rect.top < 40) {
663
+ item.style.cursor = 'move';
664
+ } else {
665
+ item.style.cursor = '';
666
+ }
667
+
668
+ if (item.style.cursor) {
669
+ controls.type = 'move';
670
+ controls.d = item.style.cursor;
671
+ } else {
672
+ controls.type = null;
673
+ controls.d = null;
674
+ }
675
+ }
571
676
  }
572
677
 
573
678
  self.mousedown = function(e) {
@@ -583,6 +688,8 @@ if (!lemonade && typeof (require) === 'function') {
583
688
  controls.e = item;
584
689
  controls.w = rect.width;
585
690
  controls.h = rect.height;
691
+ controls.t = rect.top;
692
+ controls.l = rect.left;
586
693
  // If is not minimized
587
694
  if (controls.type === 'resize') {
588
695
  // Make sure the width and height is defined for the modal
@@ -599,14 +706,11 @@ if (!lemonade && typeof (require) === 'function') {
599
706
  controls.e.classList.remove('action');
600
707
  }
601
708
  controls.e.classList.add('action');
602
- } else if (isTrue(self.draggable) && self.title && y - rect.top < 40) {
603
- // Action
604
- controls.type = 'move';
709
+ } else if (isTrue(self.draggable) && y - rect.top < 40) {
605
710
  // Callback
606
711
  controls.action = function () {
607
712
  self.top = parseInt(item.style.top);
608
713
  self.left = parseInt(item.style.left);
609
-
610
714
  controls.e.classList.remove('action');
611
715
  }
612
716
  controls.e.classList.add('action');
@@ -617,36 +721,16 @@ if (!lemonade && typeof (require) === 'function') {
617
721
  }
618
722
 
619
723
  self.click = function(e) {
620
- // Get mouse coordinates
621
- let [x,y] = getCoords(e);
622
- // Get the position and dimensions
623
- let rect = self.el.getBoundingClientRect();
624
- // Right
625
- let right = rect.width - (x - rect.left);
626
- // Corner
627
- let corner = (y - rect.top) < 40 && right > 10 && right < 34;
628
- // Check if the click in on close
629
- if (isTrue(self.closable)) {
630
- if (corner) {
631
- self.closed = true;
632
-
633
- if (isTrue(self.minimizable)) {
634
- removeMini(self);
635
- }
636
- return;
637
- }
638
-
639
- corner = (y - rect.top) < 40 && right > 10 && right < 65;
724
+ if (e.target.classList.contains('lm-modal-close')) {
725
+ self.closed = true;
640
726
  }
641
- // Check if the click in on minimize
642
- if (isTrue(self.minimizable)) {
643
- if (corner) {
644
- // Handles minimized modal positioning
645
- if (self.minimized === true) {
646
- removeMini(self);
647
- } else {
648
- setMini(self);
649
- }
727
+
728
+ if (e.target.classList.contains('lm-modal-minimize')) {
729
+ // Handles minimized modal positioning
730
+ if (self.minimized === true) {
731
+ removeMini(self);
732
+ } else {
733
+ setMini(self);
650
734
  }
651
735
  }
652
736
  }
@@ -663,37 +747,35 @@ if (!lemonade && typeof (require) === 'function') {
663
747
  }
664
748
  }
665
749
 
750
+ if (! template) {
751
+ template = '';
752
+ }
753
+
666
754
  return `<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" onmousedown="self.mousedown" onmousemove="self.mousemove" onclick="self.click" tabindex="-1">
667
- <div class="lm-modal-title" data-icon="{{self.icon}}">{{self.title}}</div>
755
+ <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>
668
756
  <div>${template}</div>
669
757
  </div>`
670
758
  }
671
759
 
672
- lemonade.setComponents({ Modal: Modal });
673
-
674
- return function (root, options, template) {
760
+ const Component = function (root, options, template) {
675
761
  if (typeof(root) === 'object') {
676
- if (! template) {
677
- template = '';
678
- }
679
- // Keep the DOM elements
680
- let elements = [];
681
- while (root.firstChild) {
682
- elements.push(root.firstChild);
683
- root.firstChild.remove();
684
- }
762
+ // Remove elements from the DOM
763
+ let elements = removeElements(root);
685
764
  // Create the modal
686
765
  let e = lemonade.render(Modal, root, options, template);
687
- // Append any elements inside the modal
688
- if (elements.length) {
689
- while (elements[0]) {
690
- e.children[1].appendChild(elements[0]);
691
- elements.shift();
692
- }
693
- }
766
+ // Add elements to the container
767
+ appendElements(e.children[1], elements);
768
+
694
769
  return options;
695
770
  } else {
696
- return Modal.call(this, root);
771
+ return Modal.call(this);
697
772
  }
698
773
  }
774
+
775
+ // Create LemonadeJS Component
776
+ lemonade.setComponents({ Modal: Modal });
777
+ // Create Web Component
778
+ lemonade.createWebComponent('modal', Modal)
779
+
780
+ return Component;
699
781
  })));
package/dist/react.d.ts CHANGED
@@ -5,13 +5,16 @@
5
5
  */
6
6
 
7
7
 
8
- import ModalComponent from './index';
8
+ import Component from './index';
9
9
 
10
10
  interface Modal {
11
+ ref?: MutableRefObject<undefined>;
11
12
  (): any
12
13
  [key: string]: any
13
14
  }
14
15
 
15
- declare function Modal<Modal>(props: ModalComponent.Options): any;
16
+ type Props = IntrinsicAttributes & Component.Options & Modal;
17
+
18
+ declare function Modal<Modal>(props: Props): any;
16
19
 
17
20
  export default Modal;
package/dist/style.css CHANGED
@@ -8,7 +8,6 @@
8
8
  box-sizing: border-box;
9
9
  box-shadow: 0 0 12px rgb(0 0 0 / 22%);
10
10
  opacity: 1;
11
- will-change: transform;
12
11
  border: 1px solid var(--lm-border-color, #ccc);
13
12
  outline: none;
14
13
  margin: 0;
@@ -18,6 +17,10 @@
18
17
  color: var(--lm-font-color, #000);
19
18
  }
20
19
 
20
+ .lm-modal.action {
21
+ user-select: none;
22
+ }
23
+
21
24
  .lm-modal-title {
22
25
  width: 100%;
23
26
  border-bottom: 1px solid var(--lm-border-color, #ccc);
@@ -30,52 +33,58 @@
30
33
  border-radius: 5px;
31
34
  }
32
35
 
33
- .lm-modal-title:empty {
36
+ .lm-modal .lm-modal-title {
34
37
  display: none;
35
38
  }
36
39
 
37
- .lm-modal-title[data-icon]::before {
38
- content: attr(data-icon);
40
+ .lm-modal .lm-modal-title[data-icon],
41
+ .lm-modal .lm-modal-title[data-title],
42
+ .lm-modal[closable="true"] .lm-modal-title,
43
+ .lm-modal[minimizable="true"] .lm-modal-title {
44
+ display: inherit;
45
+ }
46
+
47
+ .lm-modal-title > div:nth-child(2) {
48
+ flex: 1;
49
+ }
50
+
51
+ .lm-modal .lm-modal-icon {
39
52
  width: 24px;
40
53
  height: 24px;
41
54
  font-size: 24px;
55
+ cursor: pointer;
42
56
  font-family: "Material Icons";
43
- margin-right: 5px;
57
+ text-align: center;
58
+ display: none;
44
59
  }
45
60
 
46
- .lm-modal[closable="true"]::after {
61
+ .lm-modal .lm-modal-icon:not(:empty) {
62
+ display: inherit;
63
+ }
64
+
65
+ .lm-modal .lm-modal-close::before {
47
66
  content: 'close';
48
- width: 24px;
49
- height: 24px;
50
- font-size: 24px;
51
- font-family: "Material Icons";
52
- position: absolute;
53
- top: 10px;
54
- right: 10px;
55
- cursor: pointer;
56
67
  }
57
68
 
58
- .lm-modal[minimizable="true"]::before {
69
+ .lm-modal .lm-modal-minimize::before {
59
70
  content: '\2500';
60
- width: 24px;
61
- height: 24px;
62
- font-size: 24px;
63
- font-family: "Material Icons";
64
- position: absolute;
65
- top: 10px;
66
- right: 15px;
67
- cursor: pointer;
68
71
  }
69
72
 
70
- .lm-modal[closable="true"].lm-modal[minimizable="true"]::before {
71
- right: 35px;
73
+ .lm-modal div[data-icon] .lm-modal-feature,
74
+ .lm-modal[minimizable="true"] .lm-modal-minimize {
75
+ margin-right: 5px;
76
+ display: block;
77
+ }
78
+
79
+ .lm-modal[closable="true"] .lm-modal-close {
80
+ display: block;
72
81
  }
73
82
 
74
83
  .lm-modal[closed="true"] {
75
- display: none !important;
84
+ display: none;
76
85
  }
77
86
 
78
- .lm-modal[minimized="true"]:before {
87
+ .lm-modal[minimized="true"] .lm-modal-minimize::before {
79
88
  content: '\e5d7';
80
89
  }
81
90
 
package/package.json CHANGED
@@ -13,9 +13,9 @@
13
13
  "modal js"
14
14
  ],
15
15
  "dependencies": {
16
- "lemonadejs": "^4.2.1"
16
+ "lemonadejs": "^4.3.2"
17
17
  },
18
18
  "main": "dist/index.js",
19
19
  "types": "dist/index.d.ts",
20
- "version": "2.8.0"
20
+ "version": "3.1.0"
21
21
  }