@lemonadejs/contextmenu 1.3.0 → 5.0.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
@@ -42,14 +42,12 @@ if (! Modal && typeof (require) === 'function') {
42
42
  }
43
43
  }
44
44
 
45
- self.hasSubmenu = !! self.submenu;
46
-
47
45
  if (self.type === 'line') {
48
46
  return `<hr />`;
49
47
  } else if (self.type === 'inline') {
50
48
  return `<div></div>`;
51
49
  } else {
52
- return `<div class="lm-menu-item" data-disabled="{{self.disabled}}" data-cursor="{{self.cursor}}" data-icon="{{self.icon}}" data-submenu="{{self.hasSubmenu}}" onmouseup="self.parent.parent.mouseUp(self, e)" onmouseenter="self.parent.parent.mouseEnter(self)" onmouseleave="self.parent.parent.mouseLeave(self)">
50
+ return `<div class="lm-menu-item" data-disabled="{{self.disabled}}" data-cursor="{{self.cursor}}" data-icon="{{self.icon}}" data-submenu="${!!self.submenu}" onmouseup="self.parent.mouseUp" onmouseenter="self.parent.mouseEnter" onmouseleave="self.parent.mouseLeave">
53
51
  <a>{{self.title}}</a> <div>{{self.shortcut}}</div>
54
52
  </div>`;
55
53
  }
@@ -63,10 +61,13 @@ if (! Modal && typeof (require) === 'function') {
63
61
  // Save the position of this modal
64
62
  let index = self.parent.modals.length;
65
63
 
64
+ // Blank options
65
+ self.options = [];
66
+
66
67
  // Close handler
67
68
  self.onclose = function() {
68
69
  // Reset any cursor
69
- resetCursor.call(self.modal);
70
+ resetCursor.call(self);
70
71
  // Parent
71
72
  if (typeof(self.parent.onclose) === 'function') {
72
73
  self.parent.onclose(self.parent, self);
@@ -96,39 +97,37 @@ if (! Modal && typeof (require) === 'function') {
96
97
  self.open = function(s, cursor) {
97
98
  if (s.submenu) {
98
99
  // Get the modal in the container of modals
99
- let item = self.parent.modals[index+1];
100
- if (! item) {
100
+ let current = self.parent.modals[index+1];
101
+ // Do not exist yet, create it.
102
+ if (! current) {
101
103
  // Modal need to be created
102
- item = self.parent.create();
104
+ current = self.parent.create();
103
105
  }
104
106
  // Get the parent from this one
105
- let parent = self.parent.modals[index].modal;
106
- // Get the self of the modal
107
- let modal = item.modal;
107
+ let parent = self.parent.modals[index];
108
108
  // Update modal content
109
- if (modal.options !== s.submenu) {
109
+ if (current.options !== s.submenu) {
110
110
  // Close modals with higher level
111
- modal.options = s.submenu;
111
+ current.options = s.submenu;
112
112
  // Close other modals
113
113
  self.parent.close(index+1);
114
114
  }
115
- // Open modal
116
- modal.closed = false;
117
115
  // Update selected modal
118
116
  self.parent.modalIndex = index+1;
119
- // Define the position
120
- modal.top = parent.top + s.el.offsetTop + 2;
121
- modal.left = parent.left + 248;
117
+ // Update modal
118
+ current.modal.closed = false;
119
+ current.modal.top = parent.modal.top + s.el.offsetTop + 2;
120
+ current.modal.left = parent.modal.left + 248;
122
121
 
123
122
  // Activate the cursor
124
123
  if (cursor === true) {
125
124
  // Place cursor in the first position
126
- modal.options[0].cursor = true;
125
+ current.options[0].cursor = true;
127
126
  // Position cursor
128
- modal.cursor = 0;
127
+ current.cursor = 0;
129
128
  }
130
129
 
131
- onopen(modal, s.submenu)
130
+ onopen(current, s.submenu)
132
131
  } else {
133
132
  // Close modals with higher level
134
133
  self.parent.close(index+1);
@@ -136,7 +135,7 @@ if (! Modal && typeof (require) === 'function') {
136
135
  }
137
136
 
138
137
  // Mouse open
139
- self.mouseUp = function(s, e) {
138
+ self.mouseUp = function(e, s) {
140
139
  if (typeof(s.onclick) === 'function') {
141
140
  s.onclick.call(s, e, s.el);
142
141
  }
@@ -145,7 +144,7 @@ if (! Modal && typeof (require) === 'function') {
145
144
  }
146
145
  }
147
146
 
148
- self.mouseEnter = function(s) {
147
+ self.mouseEnter = function(e, s) {
149
148
  if (delayTimer) {
150
149
  clearTimeout(delayTimer);
151
150
  }
@@ -154,17 +153,17 @@ if (! Modal && typeof (require) === 'function') {
154
153
  }, 200);
155
154
  }
156
155
 
157
- self.mouseLeave = function() {
156
+ self.mouseLeave = function(e, s) {
158
157
  if (delayTimer) {
159
158
  clearTimeout(delayTimer);
160
159
  }
161
160
  }
162
161
 
163
- let template = `<Modal position="absolute" :overflow="true" :closed="true" :ref="self.modal" :responsive="false" :auto-adjust="true" :focus="false" :layers="false" :onopen="self.onopen" :onclose="self.onclose">
162
+ let template = `<lm-modal position="absolute" :overflow="true" :closed="true" :ref="self.modal" :responsive="false" :auto-adjust="true" :focus="false" :layers="false" :onopen="self.onopen" :onclose="self.onclose">
164
163
  <div class="lm-menu-submenu">
165
164
  <Item :loop="self.options" />
166
165
  </div>
167
- </Modal>`;
166
+ </lm-modal>`;
168
167
 
169
168
  return lemonade.element(template, self, { Item: Item });
170
169
  }
@@ -198,6 +197,7 @@ if (! Modal && typeof (require) === 'function') {
198
197
  } else {
199
198
  this.options[this.cursor].cursor = false;
200
199
  }
200
+
201
201
  // Add the cursor
202
202
  this.options[cursor].cursor = true;
203
203
  // Cursor
@@ -225,40 +225,11 @@ if (! Modal && typeof (require) === 'function') {
225
225
  }
226
226
  }
227
227
 
228
- const actionCursor = function(e) {
229
- // Contextmenu modal
230
- let item = this.options[this.cursor];
231
- // Cursor is found so reset it
232
- if (typeof(item) !== 'undefined') {
233
- // Execute action
234
- if (typeof(item.onclick) === 'function') {
235
- item.onclick.call(item, e, item.el);
236
- }
237
- // Open sub menu in case exists
238
- if (item.submenu) {
239
- this.parent.open(item);
240
- return true;
241
- }
242
- }
243
- }
244
-
245
228
  /**
246
- * Open a sub option of the contextmenu by a user action
247
- * @returns {boolean}
229
+ * Go through all items of a menu
230
+ * @param s
231
+ * @param options
248
232
  */
249
- const openSubmenu = function() {
250
- // Get the selected cursor
251
- let item = this.options[this.cursor];
252
- // Open submenu
253
- if (typeof(item) !== 'undefined') {
254
- // Open submenu in case that exists
255
- if (item.submenu && ! item.disabled) {
256
- this.parent.open(item, true);
257
- return true;
258
- }
259
- }
260
- }
261
-
262
233
  const onopen = function(s, options) {
263
234
  // Onopen
264
235
  for (let i = 0; i < options.length; i++) {
@@ -282,7 +253,7 @@ if (! Modal && typeof (require) === 'function') {
282
253
  };
283
254
  // Render the modal inside the main container
284
255
  lemonade.render(Create, self.el, s);
285
- // Add the reference of the modal in a container
256
+ // Add the reference of the modal in a container#
286
257
  self.modals.push(s);
287
258
  // Return self
288
259
  return s;
@@ -290,38 +261,41 @@ if (! Modal && typeof (require) === 'function') {
290
261
 
291
262
  self.open = function(options, x, y, e) {
292
263
  // Get the main modal
293
- let modal = self.modals[0].modal;
264
+ let menu = self.modals[0];
294
265
  // Reset cursor
295
- resetCursor.call(modal);
266
+ resetCursor.call(menu);
296
267
 
297
268
  // Current state
298
269
  if (! e || e.type === 'contextmenu') {
299
- modal.closed = false;
270
+ menu.modal.closed = false;
300
271
  } else if (e.type === 'click') {
301
- modal.closed = ! modal.closed;
272
+ menu.modal.closed = ! menu.modal.closed;
302
273
  }
303
274
  // If the modal is open and the content is different from what is shown
304
- if (modal.closed === false) {
275
+ if (menu.modal.closed === false) {
305
276
  // Close modals with higher level
306
277
  self.close(1);
307
278
  // Update the data
308
- if (modal.options !== options) {
279
+ if (menu.options !== options) {
309
280
  // Refresh content
310
- modal.options = options;
281
+ menu.options = options;
311
282
  }
312
283
  // Define new position
313
- modal.top = y;
314
- modal.left = x;
284
+ menu.modal.top = y;
285
+ menu.modal.left = x;
286
+
315
287
  onopen(self, options);
316
288
  }
317
289
  }
318
290
 
319
291
  self.close = function(level) {
320
292
  // Close all modals from the level specified
321
- self.modals.forEach(function(value, k) {
293
+ self.modals.forEach(function(menu, k) {
322
294
  if (k >= level) {
295
+ // Reset cursor
296
+ resetCursor.call(menu);
323
297
  // Close the modal
324
- value.modal.closed = true;
298
+ menu.modal.closed = true;
325
299
  }
326
300
  });
327
301
  // Keep the index of the modal that is opened
@@ -333,34 +307,80 @@ if (! Modal && typeof (require) === 'function') {
333
307
  self.root = self.el.parentNode;
334
308
  }
335
309
 
310
+ self.root.setAttribute('tabindex', -1);
311
+
312
+ // Create first menu
313
+ self.create();
314
+
315
+ // Normal click
316
+ self.root.addEventListener("click", function(e) {
317
+ if (e.target === self.root) {
318
+ self.close(0);
319
+ }
320
+ });
321
+
336
322
  // Keyboard event
337
323
  self.root.addEventListener("keydown", function(e) {
338
- // Modal object
339
- let m = self.modals[self.modalIndex].modal;
340
- // Something happens
341
- let ret = false;
342
- // Control
343
- if (e.key === 'ArrowLeft') {
344
- if (self.modalIndex > 0) {
345
- // Close modal
346
- m.parent.close();
347
- // Action happened
348
- ret = true;
324
+ // Menu object
325
+ let menu = self.modals[self.modalIndex];
326
+ // Modal must be opened
327
+ if (! menu.modal.closed) {
328
+ // Something happens
329
+ let ret = false;
330
+ // Control
331
+ if (e.key === 'ArrowLeft') {
332
+ if (self.modalIndex > 0) {
333
+ // Close modal
334
+ menu.close();
335
+ // Action happened
336
+ ret = true;
337
+ }
338
+ } else if (e.key === 'ArrowRight') {
339
+ // Get the selected cursor
340
+ let item = menu.options[menu.cursor];
341
+ // Open submenu
342
+ if (typeof (item) !== 'undefined') {
343
+ // Open submenu in case that exists
344
+ if (item.submenu && !item.disabled) {
345
+ // Open modal
346
+ menu.open(item, true);
347
+ // Action happened
348
+ ret = true;
349
+ }
350
+ }
351
+ } else if (e.key === 'ArrowUp') {
352
+ ret = setCursor.call(menu, 0);
353
+ } else if (e.key === 'ArrowDown') {
354
+ ret = setCursor.call(menu, 1);
355
+ } else if (e.key === 'Enter') {
356
+ // Contextmenu modal
357
+ let item = menu.options[menu.cursor];
358
+ // Cursor is found so reset it
359
+ if (typeof (item) !== 'undefined') {
360
+ // Execute action
361
+ if (typeof (item.onclick) === 'function') {
362
+ item.onclick.call(item, e, item.el);
363
+ }
364
+ // Open sub menu in case exists
365
+ if (item.submenu) {
366
+ // Open menu
367
+ menu.open(item, true);
368
+ // Action happened
369
+ ret = true;
370
+ } else {
371
+ // Close all menu
372
+ self.close(0);
373
+ // Action happened
374
+ ret = true;
375
+ }
376
+ }
349
377
  }
350
- } else if (e.key === 'ArrowRight') {
351
- ret = openSubmenu.call(m);
352
- } else if (e.key === 'ArrowUp') {
353
- ret = setCursor.call(m, 0);
354
- } else if (e.key === 'ArrowDown') {
355
- ret = setCursor.call(m, 1);
356
- } else if (e.key === 'Enter') {
357
- ret = actionCursor.call(m, e);
358
- }
359
378
 
360
- // Something important happen so block any progression
361
- if (ret === true) {
362
- e.preventDefault();
363
- e.stopImmediatePropagation();
379
+ // Something important happen so block any progression
380
+ if (ret === true) {
381
+ e.preventDefault();
382
+ e.stopImmediatePropagation();
383
+ }
364
384
  }
365
385
  });
366
386
 
@@ -380,11 +400,6 @@ if (! Modal && typeof (require) === 'function') {
380
400
  e.preventDefault();
381
401
  e.stopImmediatePropagation();
382
402
  });
383
-
384
- self.root.setAttribute('tabindex', -1);
385
-
386
- // Create first menu
387
- self.create();
388
403
  }
389
404
 
390
405
  return `<div class="lm-menu"></div>`;
package/dist/style.css CHANGED
@@ -22,7 +22,7 @@
22
22
  .lm-menu-submenu > div.lm-menu-item {
23
23
  box-sizing: border-box;
24
24
  display: flex;
25
- padding: 0 8px 0 8px;
25
+ padding: 0 8px 0 30px;
26
26
  width: 250px;
27
27
  font-size: 11px;
28
28
  font-family:sans-serif;
@@ -60,8 +60,8 @@
60
60
  .lm-menu-submenu hr {
61
61
  border: 1px solid var(--lm-border-color-light, #e9e9e9);
62
62
  border-bottom: 0;
63
- margin-top:5px;
64
- margin-bottom:5px;
63
+ margin-top: 5px;
64
+ margin-bottom: 5px;
65
65
  }
66
66
 
67
67
  .lm-menu-submenu > div.lm-menu-item::before {
@@ -72,4 +72,6 @@
72
72
  margin-right: 10px;
73
73
  width: 16px;
74
74
  color: var(--lm-icon-color, #777);
75
+ position: absolute;
76
+ left: 8px;
75
77
  }
package/package.json CHANGED
@@ -14,10 +14,10 @@
14
14
  "build": "webpack --config webpack.config.js"
15
15
  },
16
16
  "dependencies": {
17
- "lemonadejs": "^4.3.3",
18
- "@lemonadejs/modal": "^3.2.0"
17
+ "lemonadejs": "^5.0.3",
18
+ "@lemonadejs/modal": "^5.0.0"
19
19
  },
20
20
  "main": "dist/index.js",
21
21
  "types": "dist/index.d.ts",
22
- "version": "1.3.0"
22
+ "version": "5.0.0"
23
23
  }