@vaadin/context-menu 25.2.0-alpha10 → 25.2.0-alpha12

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.
@@ -29,7 +29,11 @@
29
29
  {
30
30
  "kind": "method",
31
31
  "name": "close",
32
- "description": "Closes the overlay."
32
+ "description": "Closes the overlay.",
33
+ "inheritedFrom": {
34
+ "name": "ItemsMixin",
35
+ "module": "src/vaadin-contextmenu-items-mixin.js"
36
+ }
33
37
  },
34
38
  {
35
39
  "kind": "field",
@@ -239,6 +243,10 @@
239
243
  "description": "Controller for the tooltip slotted into `<vaadin-context-menu>`. Configures\nthe tooltip in manual mode and drives its target, context, and position\nbased on the currently hovered or focused item.",
240
244
  "name": "ContextMenuTooltipController",
241
245
  "members": [
246
+ {
247
+ "kind": "method",
248
+ "name": "bringToFront"
249
+ },
242
250
  {
243
251
  "kind": "method",
244
252
  "name": "close",
@@ -319,8 +327,8 @@
319
327
  "name": "close",
320
328
  "description": "Closes the overlay.",
321
329
  "inheritedFrom": {
322
- "name": "ContextMenuMixin",
323
- "module": "src/vaadin-context-menu-mixin.js"
330
+ "name": "ItemsMixin",
331
+ "module": "src/vaadin-contextmenu-items-mixin.js"
324
332
  }
325
333
  },
326
334
  {
@@ -639,6 +647,10 @@
639
647
  "description": "",
640
648
  "name": "ItemsMixin",
641
649
  "members": [
650
+ {
651
+ "kind": "method",
652
+ "name": "close"
653
+ },
642
654
  {
643
655
  "kind": "field",
644
656
  "name": "items",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/context-menu",
3
- "version": "25.2.0-alpha10",
3
+ "version": "25.2.0-alpha12",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -37,21 +37,21 @@
37
37
  ],
38
38
  "dependencies": {
39
39
  "@open-wc/dedupe-mixin": "^1.3.0",
40
- "@vaadin/a11y-base": "25.2.0-alpha10",
41
- "@vaadin/component-base": "25.2.0-alpha10",
42
- "@vaadin/item": "25.2.0-alpha10",
43
- "@vaadin/list-box": "25.2.0-alpha10",
44
- "@vaadin/lit-renderer": "25.2.0-alpha10",
45
- "@vaadin/overlay": "25.2.0-alpha10",
46
- "@vaadin/vaadin-themable-mixin": "25.2.0-alpha10",
40
+ "@vaadin/a11y-base": "25.2.0-alpha12",
41
+ "@vaadin/component-base": "25.2.0-alpha12",
42
+ "@vaadin/item": "25.2.0-alpha12",
43
+ "@vaadin/list-box": "25.2.0-alpha12",
44
+ "@vaadin/lit-renderer": "25.2.0-alpha12",
45
+ "@vaadin/overlay": "25.2.0-alpha12",
46
+ "@vaadin/vaadin-themable-mixin": "25.2.0-alpha12",
47
47
  "lit": "^3.0.0"
48
48
  },
49
49
  "devDependencies": {
50
- "@vaadin/aura": "25.2.0-alpha10",
51
- "@vaadin/chai-plugins": "25.2.0-alpha10",
52
- "@vaadin/test-runner-commands": "25.2.0-alpha10",
50
+ "@vaadin/aura": "25.2.0-alpha12",
51
+ "@vaadin/chai-plugins": "25.2.0-alpha12",
52
+ "@vaadin/test-runner-commands": "25.2.0-alpha12",
53
53
  "@vaadin/testing-helpers": "^2.0.0",
54
- "@vaadin/vaadin-lumo-styles": "25.2.0-alpha10",
54
+ "@vaadin/vaadin-lumo-styles": "25.2.0-alpha12",
55
55
  "sinon": "^21.0.2"
56
56
  },
57
57
  "customElements": "custom-elements.json",
@@ -59,5 +59,5 @@
59
59
  "web-types.json",
60
60
  "web-types.lit.json"
61
61
  ],
62
- "gitHead": "1303b6a3eeecb44a9d26f2b53cb56d9e906febdf"
62
+ "gitHead": "ae1e4373aec3653d63a45b6be18eee36f4b245a1"
63
63
  }
@@ -17,9 +17,6 @@ import { contextMenuItemStyles } from './styles/vaadin-context-menu-item-base-st
17
17
  *
18
18
  * @customElement vaadin-context-menu-item
19
19
  * @extends HTMLElement
20
- * @mixes DirMixin
21
- * @mixes ItemMixin
22
- * @mixes ThemableMixin
23
20
  * @protected
24
21
  */
25
22
  class ContextMenuItem extends ItemMixin(ThemableMixin(DirMixin(PolylitMixin(LumoInjectionMixin(LitElement))))) {
@@ -17,9 +17,6 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
17
17
  *
18
18
  * @customElement vaadin-context-menu-list-box
19
19
  * @extends HTMLElement
20
- * @mixes DirMixin
21
- * @mixes ListMixin
22
- * @mixes ThemableMixin
23
20
  * @protected
24
21
  */
25
22
  class ContextMenuListBox extends ListMixin(ThemableMixin(DirMixin(PolylitMixin(LumoInjectionMixin(LitElement))))) {
@@ -10,10 +10,6 @@ import { MediaQueryController } from '@vaadin/component-base/src/media-query-con
10
10
  import { ContextMenuTooltipController } from './vaadin-context-menu-tooltip-controller.js';
11
11
  import { ItemsMixin } from './vaadin-contextmenu-items-mixin.js';
12
12
 
13
- /**
14
- * @polymerMixin
15
- * @mixes ItemsMixin
16
- */
17
13
  export const ContextMenuMixin = (superClass) =>
18
14
  class ContextMenuMixinClass extends ItemsMixin(superClass) {
19
15
  static get properties() {
@@ -36,6 +32,7 @@ export const ContextMenuMixin = (superClass) =>
36
32
  value: false,
37
33
  notify: true,
38
34
  readOnly: true,
35
+ sync: true,
39
36
  },
40
37
 
41
38
  /**
@@ -135,7 +132,7 @@ export const ContextMenuMixin = (superClass) =>
135
132
  this._boundOpen = this.open.bind(this);
136
133
  this._boundClose = this.close.bind(this);
137
134
  this._boundPreventDefault = this._preventDefault.bind(this);
138
- this._boundOnGlobalContextMenu = this._onGlobalContextMenu.bind(this);
135
+ this.__onGlobalContextMenu = this.__onGlobalContextMenu.bind(this);
139
136
  }
140
137
 
141
138
  /** @protected */
@@ -144,6 +141,7 @@ export const ContextMenuMixin = (superClass) =>
144
141
 
145
142
  this.__boundOnScroll = this.__onScroll.bind(this);
146
143
  window.addEventListener('scroll', this.__boundOnScroll, true);
144
+ document.documentElement.addEventListener('contextmenu', this.__onGlobalContextMenu, true);
147
145
 
148
146
  // Restore opened state if overlay was opened when disconnecting
149
147
  if (this.__restoreOpened) {
@@ -156,10 +154,16 @@ export const ContextMenuMixin = (superClass) =>
156
154
  super.disconnectedCallback();
157
155
 
158
156
  window.removeEventListener('scroll', this.__boundOnScroll, true);
157
+ document.documentElement.removeEventListener('contextmenu', this.__onGlobalContextMenu, true);
159
158
 
160
- // Close overlay and memorize opened state
159
+ // Memorize opened state and defer close so that DOM moves (disconnect
160
+ // followed by reconnect within the same task) do not close the overlay.
161
161
  this.__restoreOpened = this.opened;
162
- this.close();
162
+ setTimeout(() => {
163
+ if (!this.isConnected) {
164
+ this.close();
165
+ }
166
+ });
163
167
  }
164
168
 
165
169
  /** @protected */
@@ -290,13 +294,7 @@ export const ContextMenuMixin = (superClass) =>
290
294
  }
291
295
 
292
296
  /** @private */
293
- _openedChanged(opened, oldOpened) {
294
- if (opened) {
295
- document.documentElement.addEventListener('contextmenu', this._boundOnGlobalContextMenu, true);
296
- } else if (oldOpened) {
297
- document.documentElement.removeEventListener('contextmenu', this._boundOnGlobalContextMenu, true);
298
- }
299
-
297
+ _openedChanged(opened) {
300
298
  this.__setListenOnUserSelect(opened);
301
299
  }
302
300
 
@@ -338,6 +336,8 @@ export const ContextMenuMixin = (superClass) =>
338
336
  * Closes the overlay.
339
337
  */
340
338
  close() {
339
+ super.close();
340
+
341
341
  this._setOpened(false);
342
342
  }
343
343
 
@@ -630,7 +630,10 @@ export const ContextMenuMixin = (superClass) =>
630
630
  }
631
631
 
632
632
  /** @private */
633
- _onGlobalContextMenu(e) {
633
+ __onGlobalContextMenu(e) {
634
+ if (!this.opened) {
635
+ return;
636
+ }
634
637
  if (!e.shiftKey) {
635
638
  const isTouchDevice = isAndroid || isIOS;
636
639
  if (!isTouchDevice) {
@@ -18,10 +18,6 @@ import { MenuOverlayMixin } from './vaadin-menu-overlay-mixin.js';
18
18
  *
19
19
  * @customElement vaadin-context-menu-overlay
20
20
  * @extends HTMLElement
21
- * @mixes DirMixin
22
- * @mixes MenuOverlayMixin
23
- * @mixes OverlayMixin
24
- * @mixes ThemableMixin
25
21
  * @protected
26
22
  */
27
23
  export class ContextMenuOverlay extends MenuOverlayMixin(
@@ -66,6 +66,11 @@ export class ContextMenuTooltipController extends SlotController {
66
66
  }
67
67
  }
68
68
 
69
+ bringToFront() {
70
+ const tooltipNode = this.node;
71
+ tooltipNode?._overlayElement?.bringToFront();
72
+ }
73
+
69
74
  /**
70
75
  * @param {boolean} immediate
71
76
  */
@@ -246,9 +246,6 @@ import { ContextMenuMixin } from './vaadin-context-menu-mixin.js';
246
246
  *
247
247
  * @customElement vaadin-context-menu
248
248
  * @extends HTMLElement
249
- * @mixes ElementMixin
250
- * @mixes ContextMenuMixin
251
- * @mixes ThemePropertyMixin
252
249
  */
253
250
  class ContextMenu extends ContextMenuMixin(ElementMixin(ThemePropertyMixin(PolylitMixin(LitElement)))) {
254
251
  static get is() {
@@ -6,9 +6,6 @@
6
6
  import { isKeyboardActive } from '@vaadin/a11y-base/src/focus-utils.js';
7
7
  import { isTouch } from '@vaadin/component-base/src/browser-utils.js';
8
8
 
9
- /**
10
- * @polymerMixin
11
- */
12
9
  export const ItemsMixin = (superClass) =>
13
10
  class ItemsMixin extends superClass {
14
11
  static get properties() {
@@ -252,6 +249,26 @@ export const ItemsMixin = (superClass) =>
252
249
  listBox.setAttribute('theme', this._theme);
253
250
  }
254
251
 
252
+ listBox.addEventListener('mouseover', (event) => {
253
+ const itemElement = event.target.closest(`${this._tagNamePrefix}-item`);
254
+ this._tooltipController.setTarget(itemElement);
255
+ this._tooltipController.open({ trigger: 'hover' });
256
+ });
257
+
258
+ listBox.addEventListener('mouseleave', () => {
259
+ this._tooltipController.close(true);
260
+ });
261
+
262
+ listBox.addEventListener('focusin', (event) => {
263
+ if (!isKeyboardActive()) {
264
+ return;
265
+ }
266
+
267
+ const itemElement = event.target.closest(`${this._tagNamePrefix}-item`);
268
+ this._tooltipController.setTarget(itemElement);
269
+ this._tooltipController.open({ trigger: 'focus' });
270
+ });
271
+
255
272
  listBox.addEventListener('selected-changed', (event) => {
256
273
  const { value } = event.detail;
257
274
  if (typeof value === 'number') {
@@ -285,31 +302,6 @@ export const ItemsMixin = (superClass) =>
285
302
  }
286
303
 
287
304
  this.__showSubMenu(event);
288
-
289
- const itemElement = event.target.closest(`${this._tagNamePrefix}-item`);
290
- this._tooltipController.setTarget(itemElement);
291
- this._tooltipController.open({ trigger: 'hover' });
292
- });
293
-
294
- overlay.addEventListener('mouseleave', (event) => {
295
- // Ignore events from the submenus
296
- if (event.composedPath().includes(this._subMenu)) {
297
- return;
298
- }
299
-
300
- this._tooltipController.close();
301
- });
302
-
303
- overlay.addEventListener('focusin', (event) => {
304
- // Ignore events from the submenus
305
- // Ignore non-keyboard focus changes (e.g. clicks).
306
- if (event.composedPath().includes(this._subMenu) || !isKeyboardActive()) {
307
- return;
308
- }
309
-
310
- const itemElement = event.target.closest(`${this._tagNamePrefix}-item`);
311
- this._tooltipController.setTarget(itemElement);
312
- this._tooltipController.open({ trigger: 'focus' });
313
305
  });
314
306
 
315
307
  overlay.addEventListener('keydown', (event) => {
@@ -350,6 +342,7 @@ export const ItemsMixin = (superClass) =>
350
342
  // host. Its tooltip controller instance is shared across sub-menus to
351
343
  // reuse the same tooltip element for items at every nesting level.
352
344
  subMenu._tooltipController = this._tooltipController;
345
+ subMenu.__parentMenu = this;
353
346
 
354
347
  subMenu._modeless = true;
355
348
  subMenu.openOn = 'opensubmenu';
@@ -374,9 +367,7 @@ export const ItemsMixin = (superClass) =>
374
367
 
375
368
  // Listen to the forwarded event from sub-menu.
376
369
  this.addEventListener('close-all-menus', () => {
377
- // Call `close()` on the overlay to close synchronously,
378
- // as we can't have `sync: true` on `opened` property.
379
- this._overlayElement.close();
370
+ this.close();
380
371
  });
381
372
 
382
373
  // Listen to the forwarded event from sub-menu.
@@ -395,7 +386,10 @@ export const ItemsMixin = (superClass) =>
395
386
 
396
387
  // Mark parent item as collapsed when closing.
397
388
  subMenu.addEventListener('opened-changed', (event) => {
398
- if (!event.detail.value) {
389
+ const opened = event.detail.value;
390
+ if (opened) {
391
+ this._tooltipController.bringToFront();
392
+ } else {
399
393
  const expandedItem = this._listBox.querySelector('[expanded]');
400
394
  if (expandedItem) {
401
395
  this.__updateExpanded(expandedItem, false);
@@ -551,4 +545,10 @@ export const ItemsMixin = (superClass) =>
551
545
  component.removeAttribute('theme');
552
546
  }
553
547
  }
548
+
549
+ close() {
550
+ if (!this.__parentMenu) {
551
+ this._tooltipController.close(true);
552
+ }
553
+ }
554
554
  };
@@ -6,9 +6,6 @@
6
6
  import { OverlayFocusMixin } from '@vaadin/overlay/src/vaadin-overlay-focus-mixin.js';
7
7
  import { PositionMixin } from '@vaadin/overlay/src/vaadin-overlay-position-mixin.js';
8
8
 
9
- /**
10
- * @polymerMixin
11
- */
12
9
  export const MenuOverlayMixin = (superClass) =>
13
10
  class MenuOverlayMixin extends OverlayFocusMixin(PositionMixin(superClass)) {
14
11
  static get properties() {
package/web-types.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/context-menu",
4
- "version": "25.2.0-alpha10",
4
+ "version": "25.2.0-alpha12",
5
5
  "description-markup": "markdown",
6
6
  "contributions": {
7
7
  "html": {
8
8
  "elements": [
9
9
  {
10
10
  "name": "vaadin-context-menu",
11
- "description": "`<vaadin-context-menu>` is a Web Component for creating context menus.\n\n### Items\n\nItems is a higher level convenience API for defining a (hierarchical) menu structure for the component.\nIf a menu item has a non-empty `children` set, a sub-menu with the child items is opened\nnext to the parent menu on mouseover, tap or a right arrow keypress.\n\nWhen an item is selected, `<vaadin-context-menu>` dispatches an \"item-selected\" event\nwith the selected item as `event.detail.value` property.\nIf item does not have `keepOpen` property the menu will be closed.\n\n```javascript\ncontextMenu.items = [\n { text: 'Menu Item 1', theme: 'primary', className: 'first', children:\n [\n { text: 'Menu Item 1-1', checked: true, keepOpen: true },\n { text: 'Menu Item 1-2' }\n ]\n },\n { component: 'hr' },\n { text: 'Menu Item 2', children:\n [\n { text: 'Menu Item 2-1' },\n { text: 'Menu Item 2-2', disabled: true }\n ]\n },\n { text: 'Menu Item 3', disabled: true, className: 'last' }\n];\n\ncontextMenu.addEventListener('item-selected', e => {\n const item = e.detail.value;\n console.log(`${item.text} selected`);\n});\n```\n\n**NOTE:** when the `items` array is defined, the renderer cannot be used.\n\n#### Disabled menu items\n\nWhen disabled, menu items are rendered as \"dimmed\".\n\nBy default, disabled items are not focusable and don't react to hover.\nAs a result, they are hidden from assistive technologies, and it's not\npossible to show a tooltip to explain why they are disabled. This can\nbe addressed by enabling the feature flag `accessibleDisabledMenuItems`,\nwhich makes disabled items focusable and hoverable, while still\npreventing them from being activated:\n\n```js\n// Set before any context menu is attached to the DOM.\nwindow.Vaadin.featureFlags.accessibleDisabledMenuItems = true;\n```\n\n#### Item tooltips\n\nMenu items can have tooltips that are shown on hover and keyboard\nfocus. To enable them, add a slotted `<vaadin-tooltip>` element\nand set the `tooltip` property on each item that should have one:\n\n```html\n<vaadin-context-menu>\n <vaadin-tooltip slot=\"tooltip\"></vaadin-tooltip>\n</vaadin-context-menu>\n```\n\n### Rendering\n\nThe content of the menu can be populated by using the renderer callback function.\n\nThe renderer function provides `root`, `contextMenu`, `model` arguments when applicable.\nGenerate DOM content by using `model` object properties if needed, append it to the `root`\nelement and control the state of the host element by accessing `contextMenu`. Before generating\nnew content, the renderer function should check if there is already content in `root` for reusing it.\n\n```html\n<vaadin-context-menu id=\"contextMenu\">\n <p>This paragraph has a context menu.</p>\n</vaadin-context-menu>\n```\n```js\nconst contextMenu = document.querySelector('#contextMenu');\ncontextMenu.renderer = (root, contextMenu, context) => {\n let listBox = root.firstElementChild;\n if (!listBox) {\n listBox = document.createElement('vaadin-list-box');\n root.appendChild(listBox);\n }\n\n let item = listBox.querySelector('vaadin-item');\n if (!item) {\n item = document.createElement('vaadin-item');\n listBox.appendChild(item);\n }\n item.textContent = 'Content of the selector: ' + context.target.textContent;\n};\n```\n\nYou can access the menu context inside the renderer using\n`context.target` and `context.detail`.\n\nRenderer is called on the opening of the context-menu and each time the related context is updated.\nDOM generated during the renderer call can be reused\nin the next renderer call and will be provided with the `root` argument.\nOn first call it will be empty.\n\n### `vaadin-contextmenu` Gesture Event\n\n`vaadin-contextmenu` is a gesture event (a custom event),\nwhich is dispatched after either `contextmenu` or long touch events.\nThis enables support for both mouse and touch environments in a uniform way.\n\n`<vaadin-context-menu>` opens the menu overlay on the `vaadin-contextmenu`\nevent by default.\n\n### Menu Listener\n\nBy default, the `<vaadin-context-menu>` element listens for the menu opening\nevent on itself. In case if you do not want to wrap the target, you can listen for\nevents on an element outside the `<vaadin-context-menu>` by setting the\n`listenOn` property:\n\n```html\n<vaadin-context-menu id=\"contextMenu\"></vaadin-context-menu>\n\n<div id=\"menuListener\">The element that listens for the contextmenu event.</div>\n```\n```javascript\nconst contextMenu = document.querySelector('#contextMenu');\ncontextMenu.listenOn = document.querySelector('#menuListener');\n```\n\n### Filtering Menu Targets\n\nBy default, the listener element and all its descendants open the context\nmenu. You can filter the menu targets to a smaller set of elements inside\nthe listener element by setting the `selector` property.\n\nIn the following example, only the elements matching `.has-menu` will open the context menu:\n\n```html\n<vaadin-context-menu selector=\".has-menu\">\n <p class=\"has-menu\">This paragraph opens the context menu</p>\n <p>This paragraph does not open the context menu</p>\n</vaadin-context-menu>\n```\n\n### Menu Context\n\nThe following properties are available in the `context` argument:\n\n- `target` is the menu opening event target, which is the element that\nthe user has called the context menu for\n- `detail` is the menu opening event detail\n\nIn the following example, the menu item text is composed with the contents\nof the element that opened the menu:\n\n```html\n<vaadin-context-menu selector=\"li\" id=\"contextMenu\">\n <ul>\n <li>Foo</li>\n <li>Bar</li>\n <li>Baz</li>\n </ul>\n</vaadin-context-menu>\n```\n```js\nconst contextMenu = document.querySelector('#contextMenu');\ncontextMenu.renderer = (root, contextMenu, context) => {\n let listBox = root.firstElementChild;\n if (!listBox) {\n listBox = document.createElement('vaadin-list-box');\n root.appendChild(listBox);\n }\n\n let item = listBox.querySelector('vaadin-item');\n if (!item) {\n item = document.createElement('vaadin-item');\n listBox.appendChild(item);\n }\n item.textContent = 'The menu target: ' + context.target.textContent;\n};\n```\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n-----------------|-------------------------------------------\n`backdrop` | Backdrop of the overlay\n`overlay` | The overlay container\n`content` | The overlay content\n\n### Custom CSS Properties\n\nThe following custom CSS properties are available for styling:\n\nCustom CSS property | Description\n--------------------------------------|-------------\n`--vaadin-context-menu-offset-top` | Used as an offset when using `position` and the context menu is aligned vertically below the target\n`--vaadin-context-menu-offset-bottom` | Used as an offset when using `position` and the context menu is aligned vertically above the target\n`--vaadin-context-menu-offset-start` | Used as an offset when using `position` and the context menu is aligned horizontally after the target\n`--vaadin-context-menu-offset-end` | Used as an offset when using `position` and the context menu is aligned horizontally before the target\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.\n\n### Internal components\n\nWhen using `items` API the following internal components are themable:\n\n- `<vaadin-context-menu-item>` - has the same API as [`<vaadin-item>`](https://cdn.vaadin.com/vaadin-web-components/25.2.0-alpha10/#/elements/vaadin-item).\n- `<vaadin-context-menu-list-box>` - has the same API as [`<vaadin-list-box>`](https://cdn.vaadin.com/vaadin-web-components/25.2.0-alpha10/#/elements/vaadin-list-box).\n\nThe `<vaadin-context-menu-item>` sub-menu elements have the following additional state attributes\non top of the built-in `<vaadin-item>` state attributes:\n\nAttribute | Description\n---------- |-------------\n`expanded` | Expanded parent item.",
11
+ "description": "`<vaadin-context-menu>` is a Web Component for creating context menus.\n\n### Items\n\nItems is a higher level convenience API for defining a (hierarchical) menu structure for the component.\nIf a menu item has a non-empty `children` set, a sub-menu with the child items is opened\nnext to the parent menu on mouseover, tap or a right arrow keypress.\n\nWhen an item is selected, `<vaadin-context-menu>` dispatches an \"item-selected\" event\nwith the selected item as `event.detail.value` property.\nIf item does not have `keepOpen` property the menu will be closed.\n\n```javascript\ncontextMenu.items = [\n { text: 'Menu Item 1', theme: 'primary', className: 'first', children:\n [\n { text: 'Menu Item 1-1', checked: true, keepOpen: true },\n { text: 'Menu Item 1-2' }\n ]\n },\n { component: 'hr' },\n { text: 'Menu Item 2', children:\n [\n { text: 'Menu Item 2-1' },\n { text: 'Menu Item 2-2', disabled: true }\n ]\n },\n { text: 'Menu Item 3', disabled: true, className: 'last' }\n];\n\ncontextMenu.addEventListener('item-selected', e => {\n const item = e.detail.value;\n console.log(`${item.text} selected`);\n});\n```\n\n**NOTE:** when the `items` array is defined, the renderer cannot be used.\n\n#### Disabled menu items\n\nWhen disabled, menu items are rendered as \"dimmed\".\n\nBy default, disabled items are not focusable and don't react to hover.\nAs a result, they are hidden from assistive technologies, and it's not\npossible to show a tooltip to explain why they are disabled. This can\nbe addressed by enabling the feature flag `accessibleDisabledMenuItems`,\nwhich makes disabled items focusable and hoverable, while still\npreventing them from being activated:\n\n```js\n// Set before any context menu is attached to the DOM.\nwindow.Vaadin.featureFlags.accessibleDisabledMenuItems = true;\n```\n\n#### Item tooltips\n\nMenu items can have tooltips that are shown on hover and keyboard\nfocus. To enable them, add a slotted `<vaadin-tooltip>` element\nand set the `tooltip` property on each item that should have one:\n\n```html\n<vaadin-context-menu>\n <vaadin-tooltip slot=\"tooltip\"></vaadin-tooltip>\n</vaadin-context-menu>\n```\n\n### Rendering\n\nThe content of the menu can be populated by using the renderer callback function.\n\nThe renderer function provides `root`, `contextMenu`, `model` arguments when applicable.\nGenerate DOM content by using `model` object properties if needed, append it to the `root`\nelement and control the state of the host element by accessing `contextMenu`. Before generating\nnew content, the renderer function should check if there is already content in `root` for reusing it.\n\n```html\n<vaadin-context-menu id=\"contextMenu\">\n <p>This paragraph has a context menu.</p>\n</vaadin-context-menu>\n```\n```js\nconst contextMenu = document.querySelector('#contextMenu');\ncontextMenu.renderer = (root, contextMenu, context) => {\n let listBox = root.firstElementChild;\n if (!listBox) {\n listBox = document.createElement('vaadin-list-box');\n root.appendChild(listBox);\n }\n\n let item = listBox.querySelector('vaadin-item');\n if (!item) {\n item = document.createElement('vaadin-item');\n listBox.appendChild(item);\n }\n item.textContent = 'Content of the selector: ' + context.target.textContent;\n};\n```\n\nYou can access the menu context inside the renderer using\n`context.target` and `context.detail`.\n\nRenderer is called on the opening of the context-menu and each time the related context is updated.\nDOM generated during the renderer call can be reused\nin the next renderer call and will be provided with the `root` argument.\nOn first call it will be empty.\n\n### `vaadin-contextmenu` Gesture Event\n\n`vaadin-contextmenu` is a gesture event (a custom event),\nwhich is dispatched after either `contextmenu` or long touch events.\nThis enables support for both mouse and touch environments in a uniform way.\n\n`<vaadin-context-menu>` opens the menu overlay on the `vaadin-contextmenu`\nevent by default.\n\n### Menu Listener\n\nBy default, the `<vaadin-context-menu>` element listens for the menu opening\nevent on itself. In case if you do not want to wrap the target, you can listen for\nevents on an element outside the `<vaadin-context-menu>` by setting the\n`listenOn` property:\n\n```html\n<vaadin-context-menu id=\"contextMenu\"></vaadin-context-menu>\n\n<div id=\"menuListener\">The element that listens for the contextmenu event.</div>\n```\n```javascript\nconst contextMenu = document.querySelector('#contextMenu');\ncontextMenu.listenOn = document.querySelector('#menuListener');\n```\n\n### Filtering Menu Targets\n\nBy default, the listener element and all its descendants open the context\nmenu. You can filter the menu targets to a smaller set of elements inside\nthe listener element by setting the `selector` property.\n\nIn the following example, only the elements matching `.has-menu` will open the context menu:\n\n```html\n<vaadin-context-menu selector=\".has-menu\">\n <p class=\"has-menu\">This paragraph opens the context menu</p>\n <p>This paragraph does not open the context menu</p>\n</vaadin-context-menu>\n```\n\n### Menu Context\n\nThe following properties are available in the `context` argument:\n\n- `target` is the menu opening event target, which is the element that\nthe user has called the context menu for\n- `detail` is the menu opening event detail\n\nIn the following example, the menu item text is composed with the contents\nof the element that opened the menu:\n\n```html\n<vaadin-context-menu selector=\"li\" id=\"contextMenu\">\n <ul>\n <li>Foo</li>\n <li>Bar</li>\n <li>Baz</li>\n </ul>\n</vaadin-context-menu>\n```\n```js\nconst contextMenu = document.querySelector('#contextMenu');\ncontextMenu.renderer = (root, contextMenu, context) => {\n let listBox = root.firstElementChild;\n if (!listBox) {\n listBox = document.createElement('vaadin-list-box');\n root.appendChild(listBox);\n }\n\n let item = listBox.querySelector('vaadin-item');\n if (!item) {\n item = document.createElement('vaadin-item');\n listBox.appendChild(item);\n }\n item.textContent = 'The menu target: ' + context.target.textContent;\n};\n```\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n-----------------|-------------------------------------------\n`backdrop` | Backdrop of the overlay\n`overlay` | The overlay container\n`content` | The overlay content\n\n### Custom CSS Properties\n\nThe following custom CSS properties are available for styling:\n\nCustom CSS property | Description\n--------------------------------------|-------------\n`--vaadin-context-menu-offset-top` | Used as an offset when using `position` and the context menu is aligned vertically below the target\n`--vaadin-context-menu-offset-bottom` | Used as an offset when using `position` and the context menu is aligned vertically above the target\n`--vaadin-context-menu-offset-start` | Used as an offset when using `position` and the context menu is aligned horizontally after the target\n`--vaadin-context-menu-offset-end` | Used as an offset when using `position` and the context menu is aligned horizontally before the target\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.\n\n### Internal components\n\nWhen using `items` API the following internal components are themable:\n\n- `<vaadin-context-menu-item>` - has the same API as [`<vaadin-item>`](https://cdn.vaadin.com/vaadin-web-components/25.2.0-alpha12/#/elements/vaadin-item).\n- `<vaadin-context-menu-list-box>` - has the same API as [`<vaadin-list-box>`](https://cdn.vaadin.com/vaadin-web-components/25.2.0-alpha12/#/elements/vaadin-list-box).\n\nThe `<vaadin-context-menu-item>` sub-menu elements have the following additional state attributes\non top of the built-in `<vaadin-item>` state attributes:\n\nAttribute | Description\n---------- |-------------\n`expanded` | Expanded parent item.",
12
12
  "attributes": [
13
13
  {
14
14
  "name": "close-on",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/context-menu",
4
- "version": "25.2.0-alpha10",
4
+ "version": "25.2.0-alpha12",
5
5
  "description-markup": "markdown",
6
6
  "framework": "lit",
7
7
  "framework-config": {
@@ -16,7 +16,7 @@
16
16
  "elements": [
17
17
  {
18
18
  "name": "vaadin-context-menu",
19
- "description": "`<vaadin-context-menu>` is a Web Component for creating context menus.\n\n### Items\n\nItems is a higher level convenience API for defining a (hierarchical) menu structure for the component.\nIf a menu item has a non-empty `children` set, a sub-menu with the child items is opened\nnext to the parent menu on mouseover, tap or a right arrow keypress.\n\nWhen an item is selected, `<vaadin-context-menu>` dispatches an \"item-selected\" event\nwith the selected item as `event.detail.value` property.\nIf item does not have `keepOpen` property the menu will be closed.\n\n```javascript\ncontextMenu.items = [\n { text: 'Menu Item 1', theme: 'primary', className: 'first', children:\n [\n { text: 'Menu Item 1-1', checked: true, keepOpen: true },\n { text: 'Menu Item 1-2' }\n ]\n },\n { component: 'hr' },\n { text: 'Menu Item 2', children:\n [\n { text: 'Menu Item 2-1' },\n { text: 'Menu Item 2-2', disabled: true }\n ]\n },\n { text: 'Menu Item 3', disabled: true, className: 'last' }\n];\n\ncontextMenu.addEventListener('item-selected', e => {\n const item = e.detail.value;\n console.log(`${item.text} selected`);\n});\n```\n\n**NOTE:** when the `items` array is defined, the renderer cannot be used.\n\n#### Disabled menu items\n\nWhen disabled, menu items are rendered as \"dimmed\".\n\nBy default, disabled items are not focusable and don't react to hover.\nAs a result, they are hidden from assistive technologies, and it's not\npossible to show a tooltip to explain why they are disabled. This can\nbe addressed by enabling the feature flag `accessibleDisabledMenuItems`,\nwhich makes disabled items focusable and hoverable, while still\npreventing them from being activated:\n\n```js\n// Set before any context menu is attached to the DOM.\nwindow.Vaadin.featureFlags.accessibleDisabledMenuItems = true;\n```\n\n#### Item tooltips\n\nMenu items can have tooltips that are shown on hover and keyboard\nfocus. To enable them, add a slotted `<vaadin-tooltip>` element\nand set the `tooltip` property on each item that should have one:\n\n```html\n<vaadin-context-menu>\n <vaadin-tooltip slot=\"tooltip\"></vaadin-tooltip>\n</vaadin-context-menu>\n```\n\n### Rendering\n\nThe content of the menu can be populated by using the renderer callback function.\n\nThe renderer function provides `root`, `contextMenu`, `model` arguments when applicable.\nGenerate DOM content by using `model` object properties if needed, append it to the `root`\nelement and control the state of the host element by accessing `contextMenu`. Before generating\nnew content, the renderer function should check if there is already content in `root` for reusing it.\n\n```html\n<vaadin-context-menu id=\"contextMenu\">\n <p>This paragraph has a context menu.</p>\n</vaadin-context-menu>\n```\n```js\nconst contextMenu = document.querySelector('#contextMenu');\ncontextMenu.renderer = (root, contextMenu, context) => {\n let listBox = root.firstElementChild;\n if (!listBox) {\n listBox = document.createElement('vaadin-list-box');\n root.appendChild(listBox);\n }\n\n let item = listBox.querySelector('vaadin-item');\n if (!item) {\n item = document.createElement('vaadin-item');\n listBox.appendChild(item);\n }\n item.textContent = 'Content of the selector: ' + context.target.textContent;\n};\n```\n\nYou can access the menu context inside the renderer using\n`context.target` and `context.detail`.\n\nRenderer is called on the opening of the context-menu and each time the related context is updated.\nDOM generated during the renderer call can be reused\nin the next renderer call and will be provided with the `root` argument.\nOn first call it will be empty.\n\n### `vaadin-contextmenu` Gesture Event\n\n`vaadin-contextmenu` is a gesture event (a custom event),\nwhich is dispatched after either `contextmenu` or long touch events.\nThis enables support for both mouse and touch environments in a uniform way.\n\n`<vaadin-context-menu>` opens the menu overlay on the `vaadin-contextmenu`\nevent by default.\n\n### Menu Listener\n\nBy default, the `<vaadin-context-menu>` element listens for the menu opening\nevent on itself. In case if you do not want to wrap the target, you can listen for\nevents on an element outside the `<vaadin-context-menu>` by setting the\n`listenOn` property:\n\n```html\n<vaadin-context-menu id=\"contextMenu\"></vaadin-context-menu>\n\n<div id=\"menuListener\">The element that listens for the contextmenu event.</div>\n```\n```javascript\nconst contextMenu = document.querySelector('#contextMenu');\ncontextMenu.listenOn = document.querySelector('#menuListener');\n```\n\n### Filtering Menu Targets\n\nBy default, the listener element and all its descendants open the context\nmenu. You can filter the menu targets to a smaller set of elements inside\nthe listener element by setting the `selector` property.\n\nIn the following example, only the elements matching `.has-menu` will open the context menu:\n\n```html\n<vaadin-context-menu selector=\".has-menu\">\n <p class=\"has-menu\">This paragraph opens the context menu</p>\n <p>This paragraph does not open the context menu</p>\n</vaadin-context-menu>\n```\n\n### Menu Context\n\nThe following properties are available in the `context` argument:\n\n- `target` is the menu opening event target, which is the element that\nthe user has called the context menu for\n- `detail` is the menu opening event detail\n\nIn the following example, the menu item text is composed with the contents\nof the element that opened the menu:\n\n```html\n<vaadin-context-menu selector=\"li\" id=\"contextMenu\">\n <ul>\n <li>Foo</li>\n <li>Bar</li>\n <li>Baz</li>\n </ul>\n</vaadin-context-menu>\n```\n```js\nconst contextMenu = document.querySelector('#contextMenu');\ncontextMenu.renderer = (root, contextMenu, context) => {\n let listBox = root.firstElementChild;\n if (!listBox) {\n listBox = document.createElement('vaadin-list-box');\n root.appendChild(listBox);\n }\n\n let item = listBox.querySelector('vaadin-item');\n if (!item) {\n item = document.createElement('vaadin-item');\n listBox.appendChild(item);\n }\n item.textContent = 'The menu target: ' + context.target.textContent;\n};\n```\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n-----------------|-------------------------------------------\n`backdrop` | Backdrop of the overlay\n`overlay` | The overlay container\n`content` | The overlay content\n\n### Custom CSS Properties\n\nThe following custom CSS properties are available for styling:\n\nCustom CSS property | Description\n--------------------------------------|-------------\n`--vaadin-context-menu-offset-top` | Used as an offset when using `position` and the context menu is aligned vertically below the target\n`--vaadin-context-menu-offset-bottom` | Used as an offset when using `position` and the context menu is aligned vertically above the target\n`--vaadin-context-menu-offset-start` | Used as an offset when using `position` and the context menu is aligned horizontally after the target\n`--vaadin-context-menu-offset-end` | Used as an offset when using `position` and the context menu is aligned horizontally before the target\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.\n\n### Internal components\n\nWhen using `items` API the following internal components are themable:\n\n- `<vaadin-context-menu-item>` - has the same API as [`<vaadin-item>`](https://cdn.vaadin.com/vaadin-web-components/25.2.0-alpha10/#/elements/vaadin-item).\n- `<vaadin-context-menu-list-box>` - has the same API as [`<vaadin-list-box>`](https://cdn.vaadin.com/vaadin-web-components/25.2.0-alpha10/#/elements/vaadin-list-box).\n\nThe `<vaadin-context-menu-item>` sub-menu elements have the following additional state attributes\non top of the built-in `<vaadin-item>` state attributes:\n\nAttribute | Description\n---------- |-------------\n`expanded` | Expanded parent item.",
19
+ "description": "`<vaadin-context-menu>` is a Web Component for creating context menus.\n\n### Items\n\nItems is a higher level convenience API for defining a (hierarchical) menu structure for the component.\nIf a menu item has a non-empty `children` set, a sub-menu with the child items is opened\nnext to the parent menu on mouseover, tap or a right arrow keypress.\n\nWhen an item is selected, `<vaadin-context-menu>` dispatches an \"item-selected\" event\nwith the selected item as `event.detail.value` property.\nIf item does not have `keepOpen` property the menu will be closed.\n\n```javascript\ncontextMenu.items = [\n { text: 'Menu Item 1', theme: 'primary', className: 'first', children:\n [\n { text: 'Menu Item 1-1', checked: true, keepOpen: true },\n { text: 'Menu Item 1-2' }\n ]\n },\n { component: 'hr' },\n { text: 'Menu Item 2', children:\n [\n { text: 'Menu Item 2-1' },\n { text: 'Menu Item 2-2', disabled: true }\n ]\n },\n { text: 'Menu Item 3', disabled: true, className: 'last' }\n];\n\ncontextMenu.addEventListener('item-selected', e => {\n const item = e.detail.value;\n console.log(`${item.text} selected`);\n});\n```\n\n**NOTE:** when the `items` array is defined, the renderer cannot be used.\n\n#### Disabled menu items\n\nWhen disabled, menu items are rendered as \"dimmed\".\n\nBy default, disabled items are not focusable and don't react to hover.\nAs a result, they are hidden from assistive technologies, and it's not\npossible to show a tooltip to explain why they are disabled. This can\nbe addressed by enabling the feature flag `accessibleDisabledMenuItems`,\nwhich makes disabled items focusable and hoverable, while still\npreventing them from being activated:\n\n```js\n// Set before any context menu is attached to the DOM.\nwindow.Vaadin.featureFlags.accessibleDisabledMenuItems = true;\n```\n\n#### Item tooltips\n\nMenu items can have tooltips that are shown on hover and keyboard\nfocus. To enable them, add a slotted `<vaadin-tooltip>` element\nand set the `tooltip` property on each item that should have one:\n\n```html\n<vaadin-context-menu>\n <vaadin-tooltip slot=\"tooltip\"></vaadin-tooltip>\n</vaadin-context-menu>\n```\n\n### Rendering\n\nThe content of the menu can be populated by using the renderer callback function.\n\nThe renderer function provides `root`, `contextMenu`, `model` arguments when applicable.\nGenerate DOM content by using `model` object properties if needed, append it to the `root`\nelement and control the state of the host element by accessing `contextMenu`. Before generating\nnew content, the renderer function should check if there is already content in `root` for reusing it.\n\n```html\n<vaadin-context-menu id=\"contextMenu\">\n <p>This paragraph has a context menu.</p>\n</vaadin-context-menu>\n```\n```js\nconst contextMenu = document.querySelector('#contextMenu');\ncontextMenu.renderer = (root, contextMenu, context) => {\n let listBox = root.firstElementChild;\n if (!listBox) {\n listBox = document.createElement('vaadin-list-box');\n root.appendChild(listBox);\n }\n\n let item = listBox.querySelector('vaadin-item');\n if (!item) {\n item = document.createElement('vaadin-item');\n listBox.appendChild(item);\n }\n item.textContent = 'Content of the selector: ' + context.target.textContent;\n};\n```\n\nYou can access the menu context inside the renderer using\n`context.target` and `context.detail`.\n\nRenderer is called on the opening of the context-menu and each time the related context is updated.\nDOM generated during the renderer call can be reused\nin the next renderer call and will be provided with the `root` argument.\nOn first call it will be empty.\n\n### `vaadin-contextmenu` Gesture Event\n\n`vaadin-contextmenu` is a gesture event (a custom event),\nwhich is dispatched after either `contextmenu` or long touch events.\nThis enables support for both mouse and touch environments in a uniform way.\n\n`<vaadin-context-menu>` opens the menu overlay on the `vaadin-contextmenu`\nevent by default.\n\n### Menu Listener\n\nBy default, the `<vaadin-context-menu>` element listens for the menu opening\nevent on itself. In case if you do not want to wrap the target, you can listen for\nevents on an element outside the `<vaadin-context-menu>` by setting the\n`listenOn` property:\n\n```html\n<vaadin-context-menu id=\"contextMenu\"></vaadin-context-menu>\n\n<div id=\"menuListener\">The element that listens for the contextmenu event.</div>\n```\n```javascript\nconst contextMenu = document.querySelector('#contextMenu');\ncontextMenu.listenOn = document.querySelector('#menuListener');\n```\n\n### Filtering Menu Targets\n\nBy default, the listener element and all its descendants open the context\nmenu. You can filter the menu targets to a smaller set of elements inside\nthe listener element by setting the `selector` property.\n\nIn the following example, only the elements matching `.has-menu` will open the context menu:\n\n```html\n<vaadin-context-menu selector=\".has-menu\">\n <p class=\"has-menu\">This paragraph opens the context menu</p>\n <p>This paragraph does not open the context menu</p>\n</vaadin-context-menu>\n```\n\n### Menu Context\n\nThe following properties are available in the `context` argument:\n\n- `target` is the menu opening event target, which is the element that\nthe user has called the context menu for\n- `detail` is the menu opening event detail\n\nIn the following example, the menu item text is composed with the contents\nof the element that opened the menu:\n\n```html\n<vaadin-context-menu selector=\"li\" id=\"contextMenu\">\n <ul>\n <li>Foo</li>\n <li>Bar</li>\n <li>Baz</li>\n </ul>\n</vaadin-context-menu>\n```\n```js\nconst contextMenu = document.querySelector('#contextMenu');\ncontextMenu.renderer = (root, contextMenu, context) => {\n let listBox = root.firstElementChild;\n if (!listBox) {\n listBox = document.createElement('vaadin-list-box');\n root.appendChild(listBox);\n }\n\n let item = listBox.querySelector('vaadin-item');\n if (!item) {\n item = document.createElement('vaadin-item');\n listBox.appendChild(item);\n }\n item.textContent = 'The menu target: ' + context.target.textContent;\n};\n```\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n-----------------|-------------------------------------------\n`backdrop` | Backdrop of the overlay\n`overlay` | The overlay container\n`content` | The overlay content\n\n### Custom CSS Properties\n\nThe following custom CSS properties are available for styling:\n\nCustom CSS property | Description\n--------------------------------------|-------------\n`--vaadin-context-menu-offset-top` | Used as an offset when using `position` and the context menu is aligned vertically below the target\n`--vaadin-context-menu-offset-bottom` | Used as an offset when using `position` and the context menu is aligned vertically above the target\n`--vaadin-context-menu-offset-start` | Used as an offset when using `position` and the context menu is aligned horizontally after the target\n`--vaadin-context-menu-offset-end` | Used as an offset when using `position` and the context menu is aligned horizontally before the target\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.\n\n### Internal components\n\nWhen using `items` API the following internal components are themable:\n\n- `<vaadin-context-menu-item>` - has the same API as [`<vaadin-item>`](https://cdn.vaadin.com/vaadin-web-components/25.2.0-alpha12/#/elements/vaadin-item).\n- `<vaadin-context-menu-list-box>` - has the same API as [`<vaadin-list-box>`](https://cdn.vaadin.com/vaadin-web-components/25.2.0-alpha12/#/elements/vaadin-list-box).\n\nThe `<vaadin-context-menu-item>` sub-menu elements have the following additional state attributes\non top of the built-in `<vaadin-item>` state attributes:\n\nAttribute | Description\n---------- |-------------\n`expanded` | Expanded parent item.",
20
20
  "extension": true,
21
21
  "attributes": [
22
22
  {