@lemonadejs/contextmenu 5.0.0 → 5.2.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 CHANGED
@@ -1,171 +1,172 @@
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
- Quick example with React
73
-
74
- ```jsx
75
- import React, { useRef } from 'react';
76
- import Contextmenu from '@lemonadejs/contextmenu/dist/react';
77
- import '@lemonadejs/contextmenu/dist/style.css';
78
- import '@lemonadejs/modal/dist/style.css';
79
-
80
- const options = [
81
- {
82
- title: 'Console.log',
83
- onclick: function () {
84
- console.log('Hello!')
85
- },
86
- },
87
- {
88
- title: 'Show Alert',
89
- onclick: function () {
90
- alert('Hello!')
91
- },
92
- },
93
- ];
94
- export default function App() {
95
- const contextmenu = useRef();
96
-
97
- return (
98
- <div style={{ backgroundColor: '#2222AA', width: '100px', height: '100px' }}>
99
- <Contextmenu options={options} ref={contextmenu} />
100
- </div>);
101
- }
102
- ```
103
-
104
- Quick example with Vue
105
-
106
- ```vue
107
- <template>
108
- <div style="background-color: #2222AA; width: 100px; height: 100px;">
109
- <Contextmenu :options="options" />
110
- </div>
111
- </template>
112
-
113
- <script>
114
- import Contextmenu from '@lemonadejs/contextmenu/dist/vue'
115
- import '@lemonadejs/contextmenu/dist/style.css';
116
- import '@lemonadejs/modal/dist/style.css';
117
-
118
- export default {
119
- name: 'App',
120
- components: {
121
- Contextmenu
122
- },
123
- data() {
124
- return {
125
- options: [
126
- {
127
- title: 'Console.log',
128
- onclick:function() {
129
- console.log('Hello!')
130
- },
131
- },
132
- {
133
- title: 'Show Alert',
134
- onclick:function() {
135
- alert('Hello!')
136
- },
137
- },
138
- ]
139
- }
140
- }
141
- }
142
- </script>
143
- ```
144
-
145
- ### Properties
146
-
147
- | Property | Type | Description |
148
- |-----------|------|-------------|
149
- | options | option[] | An array of option objects describing the rendering options. Each item should follow the structure defined in the 'Option Details' section. |
150
-
151
- ### Option Details
152
-
153
- | Property | Type | Description |
154
- |-----------|------|-------------|
155
- | submenu? | array of options | An optional array containing options displayed as a sub-menu. |
156
- | title? | string | The title text associated with the option. |
157
- | type? | string | The type of the current object, which can be utilized to display a line with 'line'. |
158
- | onclick? | function | The function executed upon selecting the option. |
159
- | icon? | string | The name of the Material Icon associated with the option. |
160
- | render? | function | The function executed when rendering the option. |
161
- | onopen? | function | The function executed when the submenu is opened. |
162
- | onclose? | function | The function executed when the submenu is closed. |
163
-
164
- ## License
165
-
166
- The [LemonadeJS](https://lemonadejs.net) Context Menu is released under the MIT.
167
-
168
- ## Other Tools
169
-
170
- - [jSuites](https://jsuites.net/docs)
171
- - [Jspreadsheet Data Grid](https://jspreadsheet.com)
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
+ Quick example with React
73
+
74
+ ```jsx
75
+ import React, { useRef } from 'react';
76
+ import Contextmenu from '@lemonadejs/contextmenu/dist/react';
77
+ import '@lemonadejs/contextmenu/dist/style.css';
78
+ import '@lemonadejs/modal/dist/style.css';
79
+
80
+ const options = [
81
+ {
82
+ title: 'Console.log',
83
+ onclick: function () {
84
+ console.log('Hello!');
85
+ },
86
+ },
87
+ {
88
+ title: 'Show Alert',
89
+ onclick: function () {
90
+ alert('Hello!');
91
+ },
92
+ },
93
+ ];
94
+ export default function App() {
95
+ const contextmenu = useRef();
96
+
97
+ return (
98
+ <div style={{ backgroundColor: '#2222AA', width: '100px', height: '100px' }}>
99
+ <Contextmenu options={options} ref={contextmenu} />
100
+ </div>
101
+ );
102
+ }
103
+ ```
104
+
105
+ Quick example with Vue
106
+
107
+ ```vue
108
+ <template>
109
+ <div style="background-color: #2222AA; width: 100px; height: 100px;">
110
+ <Contextmenu :options="options" />
111
+ </div>
112
+ </template>
113
+
114
+ <script>
115
+ import Contextmenu from '@lemonadejs/contextmenu/dist/vue';
116
+ import '@lemonadejs/contextmenu/dist/style.css';
117
+ import '@lemonadejs/modal/dist/style.css';
118
+
119
+ export default {
120
+ name: 'App',
121
+ components: {
122
+ Contextmenu,
123
+ },
124
+ data() {
125
+ return {
126
+ options: [
127
+ {
128
+ title: 'Console.log',
129
+ onclick: function () {
130
+ console.log('Hello!');
131
+ },
132
+ },
133
+ {
134
+ title: 'Show Alert',
135
+ onclick: function () {
136
+ alert('Hello!');
137
+ },
138
+ },
139
+ ],
140
+ };
141
+ },
142
+ };
143
+ </script>
144
+ ```
145
+
146
+ ### Properties
147
+
148
+ | Property | Type | Description |
149
+ | -------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
150
+ | options | option[] | An array of option objects describing the rendering options. Each item should follow the structure defined in the 'Option Details' section. |
151
+
152
+ ### Option Details
153
+
154
+ | Property | Type | Description |
155
+ | -------- | ---------------- | ------------------------------------------------------------------------------------ |
156
+ | submenu? | array of options | An optional array containing options displayed as a sub-menu. |
157
+ | title? | string | The title text associated with the option. |
158
+ | type? | string | The type of the current object, which can be utilized to display a line with 'line'. |
159
+ | onclick? | function | The function executed upon selecting the option. |
160
+ | icon? | string | The name of the Material Icon associated with the option. |
161
+ | render? | function | The function executed when rendering the option. |
162
+ | onopen? | function | The function executed when the submenu is opened. |
163
+ | onclose? | function | The function executed when the submenu is closed. |
164
+
165
+ ## License
166
+
167
+ The [LemonadeJS](https://lemonadejs.net) Context Menu is released under the MIT.
168
+
169
+ ## Other Tools
170
+
171
+ - [jSuites](https://jsuites.net/docs)
172
+ - [Jspreadsheet Data Grid](https://jspreadsheet.com)
package/dist/index.d.ts CHANGED
@@ -10,6 +10,9 @@ declare namespace Contextmenu {
10
10
  interface Item {
11
11
  submenu?: Item[];
12
12
  title?: string;
13
+ disabled?: boolean;
14
+ tooltip?: string;
15
+ shortcut?: string;
13
16
  type: 'line' | undefined;
14
17
  onclick?: (e: MouseEvent, element: HTMLElement) => void;
15
18
  icon?: string;
package/dist/index.js CHANGED
@@ -47,7 +47,7 @@ if (! Modal && typeof (require) === 'function') {
47
47
  } else if (self.type === 'inline') {
48
48
  return `<div></div>`;
49
49
  } else {
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">
50
+ return `<div class="lm-menu-item" data-disabled="{{self.disabled}}" data-cursor="{{self.cursor}}" data-icon="{{self.icon}}" title="{{self.tooltip}}" data-submenu="${!!self.submenu}" onmouseup="self.parent.mouseUp" onmouseenter="self.parent.mouseEnter" onmouseleave="self.parent.mouseLeave">
51
51
  <a>{{self.title}}</a> <div>{{self.shortcut}}</div>
52
52
  </div>`;
53
53
  }
@@ -114,10 +114,11 @@ if (! Modal && typeof (require) === 'function') {
114
114
  }
115
115
  // Update selected modal
116
116
  self.parent.modalIndex = index+1;
117
+ let rect = parent.modal.el.getBoundingClientRect();
117
118
  // Update modal
118
119
  current.modal.closed = false;
119
- current.modal.top = parent.modal.top + s.el.offsetTop + 2;
120
- current.modal.left = parent.modal.left + 248;
120
+ current.modal.top = rect.y + s.el.offsetTop + 2;
121
+ current.modal.left = rect.x + 248;
121
122
 
122
123
  // Activate the cursor
123
124
  if (cursor === true) {
@@ -159,7 +160,7 @@ if (! Modal && typeof (require) === 'function') {
159
160
  }
160
161
  }
161
162
 
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">
163
+ let template = `<lm-modal :overflow="true" :closed="true" :ref="self.modal" :responsive="false" :auto-adjust="true" :focus="false" :layers="false" :onopen="self.onopen" :onclose="self.onclose">
163
164
  <div class="lm-menu-submenu">
164
165
  <Item :loop="self.options" />
165
166
  </div>
@@ -239,7 +240,7 @@ if (! Modal && typeof (require) === 'function') {
239
240
  }
240
241
  }
241
242
 
242
- const Contextmenu = function() {
243
+ const Contextmenu = function(children, { onload }) {
243
244
  let self = this;
244
245
 
245
246
  // Container for all modals
@@ -287,7 +288,7 @@ if (! Modal && typeof (require) === 'function') {
287
288
  onopen(self, options);
288
289
  }
289
290
  }
290
-
291
+
291
292
  self.close = function(level) {
292
293
  // Close all modals from the level specified
293
294
  self.modals.forEach(function(menu, k) {
@@ -302,12 +303,12 @@ if (! Modal && typeof (require) === 'function') {
302
303
  self.modalIndex = level ? level - 1 : 0;
303
304
  }
304
305
 
305
- self.onload = function() {
306
+ onload(() => {
306
307
  if (! self.root) {
307
308
  self.root = self.el.parentNode;
308
309
  }
309
310
 
310
- self.root.setAttribute('tabindex', -1);
311
+ self.root.setAttribute('tabindex', 0);
311
312
 
312
313
  // Create first menu
313
314
  self.create();
@@ -356,7 +357,7 @@ if (! Modal && typeof (require) === 'function') {
356
357
  // Contextmenu modal
357
358
  let item = menu.options[menu.cursor];
358
359
  // Cursor is found so reset it
359
- if (typeof (item) !== 'undefined') {
360
+ if (typeof(item) !== 'undefined') {
360
361
  // Execute action
361
362
  if (typeof (item.onclick) === 'function') {
362
363
  item.onclick.call(item, e, item.el);
@@ -393,14 +394,12 @@ if (! Modal && typeof (require) === 'function') {
393
394
 
394
395
  // Parent
395
396
  self.root.addEventListener("contextmenu", function(e) {
396
- let [x,y] = getCoords(e);
397
- // Open the context menu
398
- let scrollPosition = (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
399
- self.open(self.options, x, y+scrollPosition, e);
397
+ let [x, y] = getCoords(e);
398
+ self.open(self.options, x, y, e);
400
399
  e.preventDefault();
401
400
  e.stopImmediatePropagation();
402
401
  });
403
- }
402
+ });
404
403
 
405
404
  return `<div class="lm-menu"></div>`;
406
405
  }
package/dist/style.css CHANGED
@@ -3,8 +3,8 @@
3
3
  user-select: none;
4
4
  border: 1px solid var(--lm-border-color-light, #e9e9e9);
5
5
  border-radius: 4px;
6
- box-shadow: 0 2px 6px 2px rgba(60,64,67,.2);
7
- max-height: 300px;
6
+ box-shadow: 0 2px 4px 2px rgba(60,64,67,.2);
7
+ max-height: 350px;
8
8
  width: initial;
9
9
  height: initial;
10
10
  min-width: 250px;
@@ -12,6 +12,7 @@
12
12
  padding-top: 4px;
13
13
  padding-bottom: 4px;
14
14
  z-index: 16;
15
+ transition: initial;
15
16
  }
16
17
 
17
18
  .lm-menu-submenu {
@@ -22,9 +23,9 @@
22
23
  .lm-menu-submenu > div.lm-menu-item {
23
24
  box-sizing: border-box;
24
25
  display: flex;
25
- padding: 0 8px 0 30px;
26
+ padding: 1px 8px 1px 40px;
26
27
  width: 250px;
27
- font-size: 11px;
28
+ font-size: 0.9em;
28
29
  font-family:sans-serif;
29
30
  text-align: left;
30
31
  align-items: center;
@@ -34,17 +35,19 @@
34
35
  text-decoration: none;
35
36
  flex: 1;
36
37
  cursor: pointer;
37
- line-height: 28px;
38
+ line-height: 30px;
38
39
  }
39
40
 
40
41
  .lm-menu-submenu > div.lm-menu-item div {
41
42
  margin-right: 5px;
42
- font-size: 0.9em;
43
43
  color: #888;
44
44
  }
45
45
 
46
46
  .lm-menu-submenu > div.lm-menu-item[data-submenu="true"]::after {
47
- content: '\25B6'
47
+ content: 'arrow_right';
48
+ font-family: "Material Symbols Outlined", "Material Icons", "FontAwesome";
49
+ font-size: 18px;
50
+ color: var(--lm-icon-color, #777);
48
51
  }
49
52
 
50
53
  .lm-menu-submenu > div.lm-menu-item[data-disabled="true"] {
@@ -66,12 +69,22 @@
66
69
 
67
70
  .lm-menu-submenu > div.lm-menu-item::before {
68
71
  content: attr(data-icon);
69
- font-family: 'Material Icons';
70
- font-size: 16px;
72
+ font-family: "Material Symbols Outlined", "Material Icons", "FontAwesome";
73
+ font-size: 18px;
74
+ width: 24px;
75
+ height: 24px;
71
76
  line-height: 24px;
72
- margin-right: 10px;
73
- width: 16px;
74
- color: var(--lm-icon-color, #777);
75
77
  position: absolute;
76
- left: 8px;
78
+ left: 11px;
79
+ }
80
+
81
+ .lm-dark-mode .lm-menu .lm-modal {
82
+ color: #e8e7e9;
83
+ background-color: #111;
84
+ border: 1px solid #3c3c3c;
85
+ }
86
+
87
+ .lm-dark-mode .lm-menu-submenu > div.lm-menu-item:hover,
88
+ .lm-dark-mode .lm-menu-submenu > div.lm-menu-item[data-cursor="true"] {
89
+ background-color: var(--lm-background-color-hover, #2d2d2d);
77
90
  }
package/package.json CHANGED
@@ -1,23 +1,23 @@
1
- {
2
- "name": "@lemonadejs/contextmenu",
3
- "title": "LemonadeJS contextmenu",
4
- "description": "LemonadeJS Contextmenu JavaScript Plugin",
5
- "author": {
6
- "name": "Contact <contact@lemonadejs.net>",
7
- "url": "https://lemonadejs.net"
8
- },
9
- "keywords": [
10
- "javascript contextmenu"
11
- ],
12
- "scripts": {
13
- "start": "webpack serve --history-api-fallback",
14
- "build": "webpack --config webpack.config.js"
15
- },
16
- "dependencies": {
17
- "lemonadejs": "^5.0.3",
18
- "@lemonadejs/modal": "^5.0.0"
19
- },
20
- "main": "dist/index.js",
21
- "types": "dist/index.d.ts",
22
- "version": "5.0.0"
23
- }
1
+ {
2
+ "name": "@lemonadejs/contextmenu",
3
+ "title": "LemonadeJS contextmenu",
4
+ "description": "LemonadeJS Contextmenu JavaScript Plugin",
5
+ "author": {
6
+ "name": "Contact <contact@lemonadejs.net>",
7
+ "url": "https://lemonadejs.net"
8
+ },
9
+ "keywords": [
10
+ "javascript contextmenu"
11
+ ],
12
+ "scripts": {
13
+ "start": "webpack serve --history-api-fallback",
14
+ "build": "webpack --config webpack.config.js"
15
+ },
16
+ "dependencies": {
17
+ "lemonadejs": "^5.2.0",
18
+ "@lemonadejs/modal": "^5.2.0"
19
+ },
20
+ "main": "dist/index.js",
21
+ "types": "dist/index.d.ts",
22
+ "version": "5.2.1"
23
+ }