@lemonadejs/contextmenu 1.0.1 → 1.0.3

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
@@ -2,8 +2,8 @@ if (!lemonade && typeof (require) === 'function') {
2
2
  var lemonade = require('lemonadejs');
3
3
  }
4
4
 
5
- if (!Modal && typeof (require) === 'function') {
6
- var Modal = require('@lemonadejs/modal');
5
+ if (! Modal && typeof (require) === 'function') {
6
+ var Modal = require('@lemonadejs/modal"');
7
7
  }
8
8
 
9
9
  ; (function (global, factory) {
@@ -12,9 +12,6 @@ if (!Modal && typeof (require) === 'function') {
12
12
  global.Contextmenu = factory();
13
13
  }(this, (function () {
14
14
 
15
- // Level
16
- let index = 0;
17
-
18
15
  // Get the coordinates of the action
19
16
  const getCoords = function(e) {
20
17
  let x;
@@ -32,11 +29,14 @@ if (!Modal && typeof (require) === 'function') {
32
29
  }
33
30
 
34
31
  const Item = function() {
32
+ let self = this;
35
33
  if (this.type === 'line') {
36
34
  return `<hr />`;
35
+ } else if (this.type === 'inline') {
36
+ return '<div>' + this.component() + '</div>';
37
37
  } else {
38
- return `<div data-icon="{{self.icon}}" data-submenu="{{!!self.submenu}}" onmouseover="self.parent.parent.open(e, self)">
39
- <a>{{self.title}}</a> <span>{{self.shortcut}}</span>
38
+ return `<div class="lm-menu-item" data-cursor="{{self.cursor}}" data-icon="{{self.icon}}" data-submenu="{{!!self.submenu}}" onmouseover="self.parent.parent.open(self)">
39
+ <a>{{self.title}}</a> <div>{{self.shortcut}}</div>
40
40
  </div>`;
41
41
  }
42
42
  }
@@ -44,38 +44,58 @@ if (!Modal && typeof (require) === 'function') {
44
44
  const Create = function() {
45
45
  let self = this;
46
46
 
47
- self.open = function(e, s) {
47
+ // Save the position of this modal
48
+ let index = self.parent.modals.length;
49
+
50
+ // Close handler
51
+ self.onclose = function() {
52
+ // if (typeof(value.modal.cursor) !== 'undefined') {
53
+ // value.modal.options[value.modal.cursor].cursor = false;
54
+ // delete value.modal.cursor;
55
+ // }
56
+
57
+ console.log(self.cursor,self.options);
58
+ }
59
+
60
+ // Open handler
61
+ self.open = function(s) {
48
62
  if (s.submenu) {
49
63
  // Get the modal in the container of modals
50
- let item = self.parent.modals[self.index+1];
64
+ let item = self.parent.modals[index+1];
51
65
  if (! item) {
52
66
  // Modal need to be created
53
67
  item = self.parent.create();
54
68
  }
55
69
  // Get the parent from this one
56
- let parent = self.parent.modals[self.index].modal;
70
+ let parent = self.parent.modals[index].modal;
57
71
  // Get the self of the modal
58
72
  let modal = item.modal;
59
73
 
60
74
  if (modal.options !== s.submenu) {
61
75
  // Close modals with higher level
62
76
  modal.options = s.submenu;
77
+ // Remove cursor
78
+ if (modal.cursor) {
79
+ delete modal.cursor;
80
+ }
63
81
  // Close other modals
64
- self.parent.close(self.index+1);
82
+ self.parent.close(index+1);
65
83
  }
66
84
 
67
85
  // Open modal
68
86
  modal.closed = false;
87
+ // Update selected modal
88
+ self.parent.modalIndex = index+1;
69
89
  // Define the position
70
- modal.top = parent.top + e.target.offsetTop + 2;
90
+ modal.top = parent.top + s.el.offsetTop + 2;
71
91
  modal.left = parent.left + 248;
72
92
  } else {
73
93
  // Close modals with higher level
74
- self.parent.close(self.index+1);
94
+ self.parent.close(index+1);
75
95
  }
76
96
  }
77
97
 
78
- let template = `<Modal :closed="true" :ref="self.modal">
98
+ let template = `<Modal :closed="true" :ref="self.modal" :responsive="false" :autoadjust="true" :onclose="self.onclose">
79
99
  <div class="lm-menu-submenu">
80
100
  <Item :loop="self.options" />
81
101
  </div>
@@ -84,16 +104,66 @@ if (!Modal && typeof (require) === 'function') {
84
104
  return lemonade.element(template, self, { Item: Item });
85
105
  }
86
106
 
107
+ const setCursor = function(direction) {
108
+ let cursor = null;
109
+
110
+ if (typeof(this.cursor) !== 'undefined') {
111
+ if (! direction) {
112
+ // Up
113
+ cursor = this.cursor - 1;
114
+ if (cursor < 0) {
115
+ cursor = this.options.length - 1;
116
+ }
117
+ } else {
118
+ // Down
119
+ cursor = this.cursor + 1;
120
+ if (cursor >= this.options.length) {
121
+ cursor = 0;
122
+ }
123
+ }
124
+ }
125
+
126
+ // Remove the cursor
127
+ if (cursor === null) {
128
+ if (direction) {
129
+ cursor = 0;
130
+ } else {
131
+ cursor = this.options.length - 1;
132
+ }
133
+ } else {
134
+ this.options[this.cursor].cursor = false;
135
+ }
136
+ // Add the cursor
137
+ this.options[cursor].cursor = true;
138
+ // Cursor
139
+ this.cursor = cursor;
140
+ }
141
+
142
+ const openSubmenu = function() {
143
+ if (typeof(this.options[this.cursor]) !== 'undefined') {
144
+ // Get the selected cursor
145
+ let item = this.options[this.cursor];
146
+ // Open submenu in case that exists
147
+ if (item.submenu) {
148
+ this.parent.open(item);
149
+ }
150
+ }
151
+ }
152
+
153
+ const closeSubmenu = function() {
154
+ this.parent.parent.close(this.parent.parent.modalIndex);
155
+ }
156
+
87
157
  const Contextmenu = function() {
88
158
  let self = this;
89
159
 
90
160
  // Container for all modals
91
161
  self.modals = [];
162
+ self.modalIndex = 0;
92
163
 
93
164
  self.create = function() {
94
165
  // Create a new self for each modal
95
166
  let s = {
96
- index: index++,
97
167
  parent: self,
98
168
  };
99
169
  // Render the modal inside the main container
@@ -108,12 +178,12 @@ if (!Modal && typeof (require) === 'function') {
108
178
  // Get the main modal
109
179
  let modal = self.modals[0].modal;
110
180
  // Click on the top level menu toggle the state of the menu
111
- if (e.type == 'click') {
181
+ if (e.type === 'click') {
112
182
  modal.closed = ! modal.closed;
113
- } else if (e.type == 'contextmenu') {
183
+ } else if (e.type === 'contextmenu') {
114
184
  modal.closed = false;
115
185
  }
116
-
186
+
117
187
  // If the modal is open and the content is different from what is shown
118
188
  if (modal.closed === false) {
119
189
  // Close modals with higher level
@@ -127,22 +197,42 @@ if (!Modal && typeof (require) === 'function') {
127
197
  }
128
198
  }
129
199
  }
130
-
200
+
131
201
  self.close = function(level) {
132
202
  self.modals.forEach(function(value, k) {
133
203
  if (k >= level) {
204
+ // Close the modal
134
205
  value.modal.closed = true;
135
206
  }
136
- })
207
+ });
208
+
209
+ self.modalIndex = level ? level-1 : 0;
137
210
  }
138
211
 
139
212
  self.onload = function() {
140
213
  if (! self.root) {
141
214
  self.root = self.el.parentNode;
142
215
  }
216
+ // Keyboard event
217
+ self.root.addEventListener("keydown", function(e) {
218
+ // Modal object
219
+ let m = self.modals[self.modalIndex].modal;
220
+ if (e.key === 'ArrowLeft') {
221
+ closeSubmenu.call(m);
222
+ } else if (e.key === 'ArrowRight') {
223
+ openSubmenu.call(m);
224
+ } else if (e.key === 'ArrowUp') {
225
+ setCursor.call(m, 0);
226
+ } else if (e.key === 'ArrowDown') {
227
+ setCursor.call(m, 1);
228
+ }
229
+ });
230
+
143
231
  // Create event for focus out
144
232
  self.root.addEventListener("focusout", (e) => {
145
- self.close(0);
233
+ if (! self.el.contains(e.relatedTarget)) {
234
+ self.close(0);
235
+ }
146
236
  });
147
237
  // Parent
148
238
  self.root.addEventListener("contextmenu", function(e) {
package/dist/style.css CHANGED
@@ -4,12 +4,29 @@
4
4
  border: 1px solid transparent;
5
5
  border-radius: 4px;
6
6
  box-shadow: 0 2px 6px 2px rgba(60,64,67,.15);
7
- max-height: calc(100vh - 94px);
7
+ max-height: 300px;
8
8
  overflow-y: auto;
9
9
 
10
10
  width: initial;
11
11
  height: initial;
12
+ min-width: 250px;
12
13
  min-height: initial;
14
+ padding-bottom: 6px;
15
+ }
16
+
17
+ .lm-menu .lm-modal::-webkit-scrollbar {
18
+ width: 12px;
19
+ height: 12px;
20
+ }
21
+
22
+ .lm-menu .lm-modal::-webkit-scrollbar-track {
23
+ border: 1px solid #fff;
24
+ background: #eee;
25
+ }
26
+
27
+ .lm-menu .lm-modal::-webkit-scrollbar-thumb {
28
+ border: 1px solid #fff;
29
+ background: #888;
13
30
  }
14
31
 
15
32
  .lm-menu-submenu {
@@ -17,10 +34,10 @@
17
34
  padding-bottom: 1px;
18
35
  }
19
36
 
20
- .lm-menu-submenu > div {
37
+ .lm-menu-submenu > div.lm-menu-item {
21
38
  box-sizing: border-box;
22
39
  display: flex;
23
- padding: 0 12px 0 32px;
40
+ padding: 0 8px 0 32px;
24
41
  width: 250px;
25
42
  font-size: 11px;
26
43
  font-family:sans-serif;
@@ -28,26 +45,27 @@
28
45
  align-items: center;
29
46
  }
30
47
 
31
- .lm-menu-submenu > div a {
48
+ .lm-menu-submenu > div.lm-menu-item a {
32
49
  text-decoration: none;
33
50
  flex: 1;
34
51
  cursor: pointer;
35
52
  line-height: 28px;
36
53
  }
37
54
 
38
- .lm-menu-submenu > div span {
39
- margin-right: 10px;
55
+ .lm-menu-submenu > div.lm-menu-item div {
56
+ margin-right: 5px;
40
57
  }
41
58
 
42
- .lm-menu-submenu > div[data-submenu="true"]::after {
59
+ .lm-menu-submenu > div.lm-menu-item[data-submenu="true"]::after {
43
60
  content: '\25B6'
44
61
  }
45
62
 
46
- .lm-menu-submenu > div.disabled {
63
+ .lm-menu-submenu > div.lm-menu-item.disabled {
47
64
  color: #ccc;
48
65
  }
49
66
 
50
- .lm-menu-submenu > div:hover {
67
+ .lm-menu-submenu > div.lm-menu-item:hover,
68
+ .lm-menu-submenu > div.lm-menu-item[data-cursor="true"] {
51
69
  background: #ebebeb;
52
70
  }
53
71
 
@@ -58,15 +76,12 @@
58
76
  margin-bottom:5px;
59
77
  }
60
78
 
61
- .lm-menu-submenu > div::before {
79
+ .lm-menu-submenu > div.lm-menu-item::before {
62
80
  content: attr(data-icon);
63
81
  font-family: 'Material Icons';
64
- font-size: 15px;
82
+ font-size: 16px;
65
83
  position: absolute;
66
84
  left: 9px;
67
85
  line-height: 24px;
68
- }
69
-
70
- .lm-menu-submenu.symbols > div::before {
71
- font-family: 'Material Symbols Outlined';
86
+ transform: rotate(0.03deg);
72
87
  }
package/package.json CHANGED
@@ -14,9 +14,9 @@
14
14
  "build": "webpack --config webpack.config.js"
15
15
  },
16
16
  "dependencies": {
17
- "@lemonadejs/modal": "^2.1.0",
18
- "lemonadejs": "^3.3.2"
17
+ "@lemonadejs/modal": "^2.3.1",
18
+ "lemonadejs": "^3.4.0"
19
19
  },
20
20
  "main": "dist/index.js",
21
- "version": "1.0.1"
21
+ "version": "1.0.3"
22
22
  }