@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.
- package/custom-elements.json +15 -3
- package/package.json +13 -13
- package/src/vaadin-context-menu-item.js +0 -3
- package/src/vaadin-context-menu-list-box.js +0 -3
- package/src/vaadin-context-menu-mixin.js +18 -15
- package/src/vaadin-context-menu-overlay.js +0 -4
- package/src/vaadin-context-menu-tooltip-controller.js +5 -0
- package/src/vaadin-context-menu.js +0 -3
- package/src/vaadin-contextmenu-items-mixin.js +32 -32
- package/src/vaadin-menu-overlay-mixin.js +0 -3
- package/web-types.json +2 -2
- package/web-types.lit.json +2 -2
package/custom-elements.json
CHANGED
|
@@ -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": "
|
|
323
|
-
"module": "src/vaadin-
|
|
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-
|
|
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-
|
|
41
|
-
"@vaadin/component-base": "25.2.0-
|
|
42
|
-
"@vaadin/item": "25.2.0-
|
|
43
|
-
"@vaadin/list-box": "25.2.0-
|
|
44
|
-
"@vaadin/lit-renderer": "25.2.0-
|
|
45
|
-
"@vaadin/overlay": "25.2.0-
|
|
46
|
-
"@vaadin/vaadin-themable-mixin": "25.2.0-
|
|
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-
|
|
51
|
-
"@vaadin/chai-plugins": "25.2.0-
|
|
52
|
-
"@vaadin/test-runner-commands": "25.2.0-
|
|
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-
|
|
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": "
|
|
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.
|
|
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
|
-
//
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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(
|
|
@@ -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
|
-
|
|
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
|
-
|
|
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-
|
|
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-
|
|
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",
|
package/web-types.lit.json
CHANGED
|
@@ -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-
|
|
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-
|
|
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
|
{
|