@lemonadejs/contextmenu 1.0.8 → 1.1.1

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 ADDED
@@ -0,0 +1,98 @@
1
+ # LemonadeJS Context Menu
2
+
3
+ [Official website and documentation is here](https://lemonadejs.net/docs/plugins/context-menu)
4
+
5
+ Compatible with Vanilla JavaScript, LemonadeJS, React, Vue or Angular.
6
+
7
+ The LemonadeJS Context Menu is a versatile solution for interactive menu navigation, offering a customizable and intuitive experience. Designed for efficient decision-making, users can choose options that trigger specific actions or toggle the opening of another menu—configurable to your preferences.
8
+
9
+ With a focus on flexibility, this component empowers you to tailor the menu's behavior according to your application's needs. Whether it's executing actions directly or revealing nested options for a more in-depth selection process, the Context Menu adapts seamlessly.
10
+
11
+ Noteworthy features include a user-friendly interface, allowing for smooth interactions and a clear decision-making process. The configuration options provided by the Context Menu make it a valuable addition to various applications, ensuring a responsive and adaptable menu system.
12
+
13
+ ## Getting Started
14
+
15
+ You can install using NPM or using directly from a CDN.
16
+
17
+ ### npm Installation
18
+
19
+ To install it in your project using npm, run the following command:
20
+
21
+ ```bash
22
+ $ npm install @lemonadejs/contextmenu
23
+ ```
24
+
25
+ ### CDN
26
+
27
+ To use Context Menu via a CDN, include the following script tags in your HTML file:
28
+
29
+ ```html
30
+ <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/lemonadejs/dist/lemonade.min.js"></script>
31
+ <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@lemonadejs/contextmenu/dist/index.min.js"></script>
32
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@lemonadejs/contextmenu/dist/style.min.css" />
33
+ <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@lemonadejs/modal/dist/index.min.js"></script>
34
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@lemonadejs/modal/dist/style.min.css" />
35
+ ```
36
+
37
+ ### Usage
38
+
39
+ Quick example with Lemonade
40
+
41
+ ```javascript
42
+ // Add the following link to your HTML file:
43
+ // <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Material+Icons" />
44
+ import Contextmenu from '@lemonadejs/contextmenu';
45
+ import '@lemonadejs/contextmenu/dist/style.css';
46
+ import '@lemonadejs/modal/dist/style.css';
47
+
48
+ export default function App() {
49
+ const self = this;
50
+
51
+ self.options = [
52
+ {
53
+ title: 'Console.log',
54
+ onclick:function() {
55
+ console.log('Hello!')
56
+ },
57
+ },
58
+ {
59
+ title: 'Show Alert',
60
+ onclick:function() {
61
+ alert('Hello!')
62
+ },
63
+ },
64
+ ];
65
+
66
+ return `<div style="background-color: #2222AA; width: 100px; height: 100px;">
67
+ <Contextmenu :options="self.options" :ref="self.contextmenu" />
68
+ </div>`
69
+ }
70
+ ```
71
+
72
+ ### Properties
73
+
74
+ | Property | Type | Description |
75
+ |-----------|------|-------------|
76
+ | options | option[] | An array of option objects describing the rendering options. Each item should follow the structure defined in the 'Option Details' section. |
77
+
78
+ ### Option Details
79
+
80
+ | Property | Type | Description |
81
+ |-----------|------|-------------|
82
+ | submenu? | array of options | An optional array containing options displayed as a sub-menu. |
83
+ | title? | string | The title text associated with the option. |
84
+ | type? | string | The type of the current object, which can be utilized to display a line with 'line'. |
85
+ | onclick? | function | The function executed upon selecting the option. |
86
+ | icon? | string | The name of the Material Icon associated with the option. |
87
+ | render? | function | The function executed when rendering the option. |
88
+ | onopen? | function | The function executed when the submenu is opened. |
89
+ | onclose? | function | The function executed when the submenu is closed. |
90
+
91
+ ## License
92
+
93
+ The [LemonadeJS](https://lemonadejs.net) Context Menu is released under the MIT.
94
+
95
+ ## Other Tools
96
+
97
+ - [jSuites](https://jsuites.net/v4/)
98
+ - [Jspreadsheet Data Grid](https://jspreadsheet.com)
package/dist/index.d.ts CHANGED
@@ -4,29 +4,32 @@
4
4
  * Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
5
5
  */
6
6
 
7
- interface Contextmenu {
8
- (): any
9
- [key: string]: any
10
- }
7
+ declare function Contextmenu(el: HTMLElement, options?: Contextmenu.Options): Contextmenu.Instance;
11
8
 
12
- interface Items {
13
- type: 'line' | undefined;
14
- title?: string;
15
- icon?: string;
16
- submenu?: Items[];
17
- render?: (e: MouseEvent, element: HTMLElement) => void;
18
- onclick?: (e: MouseEvent, element: HTMLElement) => void;
19
- }
9
+ declare namespace Contextmenu {
10
+ interface Item {
11
+ submenu?: Item[];
12
+ title?: string;
13
+ type: 'line' | undefined;
14
+ onclick?: (e: MouseEvent, element: HTMLElement) => void;
15
+ icon?: string;
16
+ render?: (e: MouseEvent, element: HTMLElement) => void;
17
+ /** onopen event */
18
+ onopen?: (self: object) => void;
19
+ /** onclose event */
20
+ onclose?: (self: object) => void;
21
+ }
20
22
 
21
- interface Options {
22
- /** Modal is closed */
23
- options?: Items[];
24
- }
23
+ interface Options {
24
+ /** Modal is closed */
25
+ options?: Item[];
26
+ }
25
27
 
26
- interface instance {
27
- options: boolean;
28
- open: (options: Options, x: number, y: number, e: MouseEvent) => void;
29
- close: () => void;
28
+ interface Instance {
29
+ options: boolean;
30
+ open: (options: Options, x: number, y: number, e: MouseEvent) => void;
31
+ close: () => void;
32
+ }
30
33
  }
31
34
 
32
- export declare function Modal(el: HTMLElement, options?: Options): instance;
35
+ export default Contextmenu;
package/dist/index.js CHANGED
@@ -25,6 +25,11 @@ if (! Modal && typeof (require) === 'function') {
25
25
  y = e.clientY;
26
26
  }
27
27
 
28
+ // Adjust for any scrollable parent element
29
+ let b = document.body;
30
+ x -= b.scrollLeft;
31
+ y -= b.scrollTop;
32
+
28
33
  return [x,y];
29
34
  }
30
35
 
@@ -60,6 +65,17 @@ if (! Modal && typeof (require) === 'function') {
60
65
  self.onclose = function() {
61
66
  // Reset any cursor
62
67
  resetCursor.call(self.modal);
68
+ // Parent
69
+ if (typeof(self.parent.onclose) === 'function') {
70
+ self.parent.onclose(self.parent, self);
71
+ }
72
+ }
73
+
74
+ self.onopen = function() {
75
+ // Parent
76
+ if (typeof(self.parent.onopen) === 'function') {
77
+ self.parent.onopen(self.parent, self);
78
+ }
63
79
  }
64
80
 
65
81
  /**
@@ -109,6 +125,8 @@ if (! Modal && typeof (require) === 'function') {
109
125
  // Position cursor
110
126
  modal.cursor = 0;
111
127
  }
128
+
129
+ onopen(modal, s.submenu)
112
130
  } else {
113
131
  // Close modals with higher level
114
132
  self.parent.close(index+1);
@@ -140,7 +158,7 @@ if (! Modal && typeof (require) === 'function') {
140
158
  }
141
159
  }
142
160
 
143
- let template = `<Modal :overflow="true" :closed="true" :ref="self.modal" :responsive="false" :auto-adjust="true" :onclose="self.onclose" :focus="false" :layers="false">
161
+ 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">
144
162
  <div class="lm-menu-submenu">
145
163
  <Item :loop="self.options" />
146
164
  </div>
@@ -186,6 +204,8 @@ if (! Modal && typeof (require) === 'function') {
186
204
  if (this.options[cursor].type === 'line') {
187
205
  setCursor.call(this, direction);
188
206
  }
207
+
208
+ return true;
189
209
  }
190
210
 
191
211
  /**
@@ -237,6 +257,15 @@ if (! Modal && typeof (require) === 'function') {
237
257
  }
238
258
  }
239
259
 
260
+ const onopen = function(s, options) {
261
+ // Onopen
262
+ for (let i = 0; i < options.length; i++) {
263
+ if (typeof(options[i].onopen) === 'function') {
264
+ options[i].onopen(s);
265
+ }
266
+ }
267
+ }
268
+
240
269
  const Contextmenu = function() {
241
270
  let self = this;
242
271
 
@@ -269,7 +298,6 @@ if (! Modal && typeof (require) === 'function') {
269
298
  } else if (e.type === 'click') {
270
299
  modal.closed = ! modal.closed;
271
300
  }
272
-
273
301
  // If the modal is open and the content is different from what is shown
274
302
  if (modal.closed === false) {
275
303
  // Close modals with higher level
@@ -282,6 +310,7 @@ if (! Modal && typeof (require) === 'function') {
282
310
  // Refresh content
283
311
  modal.options = options;
284
312
  }
313
+ onopen(self, options);
285
314
  }
286
315
  }
287
316
 
@@ -319,9 +348,9 @@ if (! Modal && typeof (require) === 'function') {
319
348
  } else if (e.key === 'ArrowRight') {
320
349
  ret = openSubmenu.call(m);
321
350
  } else if (e.key === 'ArrowUp') {
322
- setCursor.call(m, 0);
351
+ ret = setCursor.call(m, 0);
323
352
  } else if (e.key === 'ArrowDown') {
324
- setCursor.call(m, 1);
353
+ ret = setCursor.call(m, 1);
325
354
  } else if (e.key === 'Enter') {
326
355
  ret = actionCursor.call(m, e);
327
356
  }
@@ -336,7 +365,7 @@ if (! Modal && typeof (require) === 'function') {
336
365
  // Create event for focus out
337
366
  self.root.addEventListener("focusout", (e) => {
338
367
  if (! self.root.contains(e.relatedTarget)) {
339
- self.close(0);
368
+ //self.close(0);
340
369
  }
341
370
  });
342
371
 
@@ -344,7 +373,7 @@ if (! Modal && typeof (require) === 'function') {
344
373
  self.root.addEventListener("contextmenu", function(e) {
345
374
  let [x,y] = getCoords(e);
346
375
  // Open the context menu
347
- var scrollPosition = (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
376
+ let scrollPosition = (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
348
377
  self.open(self.options, x, y+scrollPosition, e);
349
378
  e.preventDefault();
350
379
  e.stopImmediatePropagation();
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Official Type definitions for the LemonadeJS plugins
3
+ * https://lemonadejs.net
4
+ * Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
5
+ */
6
+ import Component from './index';
7
+
8
+ interface Contextmenu {
9
+ (): any
10
+ [key: string]: any
11
+ }
12
+
13
+ declare function Contextmenu<Contextmenu>(props: Component.Options): any;
14
+
15
+ export default Contextmenu;
package/dist/style.css CHANGED
@@ -19,7 +19,7 @@
19
19
  .lm-menu-submenu > div.lm-menu-item {
20
20
  box-sizing: border-box;
21
21
  display: flex;
22
- padding: 0 8px 0 32px;
22
+ padding: 0 8px 0 8px;
23
23
  width: 250px;
24
24
  font-size: 11px;
25
25
  font-family:sans-serif;
@@ -64,7 +64,7 @@
64
64
  content: attr(data-icon);
65
65
  font-family: 'Material Icons';
66
66
  font-size: 16px;
67
- position: absolute;
68
- left: 9px;
69
67
  line-height: 24px;
68
+ margin-right: 10px;
69
+ width: 16px;
70
70
  }
package/dist/vue.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Official Type definitions for the LemonadeJS plugins
3
+ * https://lemonadejs.net
4
+ * Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
5
+ */
6
+ import Component from './index';
7
+
8
+ interface Contextmenu {
9
+ (): any
10
+ [key: string]: any
11
+ }
12
+
13
+ declare function Contextmenu<Contextmenu>(props: Component.Options): any;
14
+
15
+ export default Contextmenu;
package/package.json CHANGED
@@ -14,10 +14,10 @@
14
14
  "build": "webpack --config webpack.config.js"
15
15
  },
16
16
  "dependencies": {
17
- "@lemonadejs/modal": "^2.4.4",
17
+ "@lemonadejs/modal": "^2.7.1",
18
18
  "lemonadejs": "^4.0.7"
19
19
  },
20
20
  "main": "dist/index.js",
21
21
  "types": "dist/index.d.ts",
22
- "version": "1.0.8"
22
+ "version": "1.1.1"
23
23
  }